home *** CD-ROM | disk | FTP | other *** search
/ Aminet 48 / Aminet 48 (2002)(GTI - Schatztruhe)[!][Apr 2002].iso / Aminet / text / edit / vim60src.lha / Vim / vim60 / src / ex_getln.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-09-19  |  106.1 KB  |  4,549 lines

  1. /* vi:set ts=8 sts=4 sw=4:
  2.  *
  3.  * VIM - Vi IMproved    by Bram Moolenaar
  4.  *
  5.  * Do ":help uganda"  in Vim to read copying and usage conditions.
  6.  * Do ":help credits" in Vim to see a list of people who contributed.
  7.  * See README.txt for an overview of the Vim source code.
  8.  */
  9.  
  10. /*
  11.  * ex_getln.c: Functions for entering and editing an Ex command line.
  12.  */
  13.  
  14. #include "vim.h"
  15.  
  16. /*
  17.  * Variables shared between getcmdline(), redrawcmdline() and others.
  18.  * These need to be saved when using CTRL-R |, that's why they are in a
  19.  * structure.
  20.  */
  21. struct cmdline_info
  22. {
  23.     char_u    *cmdbuff;    /* pointer to command line buffer */
  24.     int        cmdbufflen;    /* length of cmdbuff */
  25.     int        cmdlen;        /* number of chars in command line */
  26.     int        cmdpos;        /* current cursor position */
  27.     int        cmdspos;    /* cursor column on screen */
  28.     int        cmdfirstc;    /* ':', '/', '?', '=' or NUL */
  29.     int        cmdindent;    /* number of spaces before cmdline */
  30.     char_u    *cmdprompt;    /* message in front of cmdline */
  31.     int        cmdattr;    /* attributes for prompt */
  32.     int        overstrike;    /* Typing mode on the command line.  Shared by
  33.                    getcmdline() and put_on_cmdline(). */
  34. };
  35.  
  36. static struct cmdline_info ccline;    /* current cmdline_info */
  37.  
  38. static int    cmd_numfiles = -1;    /* number of files found by
  39.                             file name completion */
  40. static char_u    **cmd_files = NULL;    /* list of files */
  41.  
  42. #ifdef FEAT_CMDHIST
  43. typedef struct hist_entry
  44. {
  45.     int        hisnum;        /* identifying number */
  46.     char_u    *hisstr;    /* actual entry */
  47. } histentry_T;
  48.  
  49. static histentry_T *(history[HIST_COUNT]) = {NULL, NULL, NULL, NULL, NULL};
  50. static int    hisidx[HIST_COUNT] = {-1, -1, -1, -1, -1};  /* lastused entry */
  51. static int    hisnum[HIST_COUNT] = {0, 0, 0, 0, 0};
  52.             /* identifying (unique) number of newest history entry */
  53. static int    hislen = 0;        /* actual length of history tables */
  54.  
  55. static int    hist_char2type __ARGS((int c));
  56. static void    init_history __ARGS((void));
  57.  
  58. static int    in_history __ARGS((int, char_u *, int));
  59. # ifdef FEAT_EVAL
  60. static int    calc_hist_idx __ARGS((int histype, int num));
  61. # endif
  62. #endif
  63.  
  64. #ifdef FEAT_RIGHTLEFT
  65. static int    cmd_hkmap = 0;    /* Hebrew mapping during command line */
  66. #endif
  67.  
  68. #ifdef FEAT_FKMAP
  69. static int    cmd_fkmap = 0;    /* Farsi mapping during command line */
  70. #endif
  71.  
  72. static int    cmdline_charsize __ARGS((int idx));
  73. static void    set_cmdspos __ARGS((void));
  74. static void    set_cmdspos_cursor __ARGS((void));
  75. static void    alloc_cmdbuff __ARGS((int len));
  76. static int    realloc_cmdbuff __ARGS((int len));
  77. #ifdef FEAT_WILDMENU
  78. static void    cmdline_del __ARGS((int from));
  79. #endif
  80. static void    redrawcmdprompt __ARGS((void));
  81. static void    cursorcmd __ARGS((void));
  82. static int    ccheck_abbr __ARGS((int));
  83. static int    nextwild __ARGS((expand_T *xp, int type, int options));
  84. static int    showmatches __ARGS((expand_T *xp, int wildmenu));
  85. static void    set_expand_context __ARGS((expand_T *xp));
  86. static int    ExpandFromContext __ARGS((expand_T *xp, char_u *, int *, char_u ***, int));
  87. #ifdef FEAT_CMDL_COMPL
  88. static int    ExpandRTDir __ARGS((char_u *pat, int *num_file, char_u ***file, char *dirname));
  89. #endif
  90.  
  91. #ifdef FEAT_CMDWIN
  92. static int    ex_window __ARGS((void));
  93. #endif
  94.  
  95. /*
  96.  * getcmdline() - accept a command line starting with firstc.
  97.  *
  98.  * firstc == ':'        get ":" command line.
  99.  * firstc == '/' or '?'        get search pattern
  100.  * firstc == '='        get expression
  101.  * firstc == '@'        get text for input() function
  102.  * firstc == '>'        get text for debug mode
  103.  * firstc == NUL        get text for :insert command
  104.  * firstc == -1            like NUL, and break on CTRL-C
  105.  *
  106.  * The line is collected in ccline.cmdbuff, which is reallocated to fit the
  107.  * command line.
  108.  *
  109.  * Careful: getcmdline() can be called recursively!
  110.  *
  111.  * Return pointer to allocated string if there is a commandline, NULL
  112.  * otherwise.
  113.  */
  114. /*ARGSUSED*/
  115.     char_u *
  116. getcmdline(firstc, count, indent)
  117.     int        firstc;
  118.     long    count;        /* only used for incremental search */
  119.     int        indent;        /* indent for inside conditionals */
  120. {
  121.     int        c;
  122.     int        i;
  123.     int        j;
  124.     int        gotesc = FALSE;        /* TRUE when <ESC> just typed */
  125.     int        do_abbr;        /* when TRUE check for abbr. */
  126. #ifdef FEAT_CMDHIST
  127.     char_u    *lookfor = NULL;    /* string to match */
  128.     int        hiscnt;            /* current history line in use */
  129.     int        histype;        /* history type to be used */
  130. #endif
  131. #ifdef FEAT_SEARCH_EXTRA
  132.     pos_T    old_cursor;
  133.     colnr_T    old_curswant;
  134.     colnr_T    old_leftcol;
  135.     linenr_T    old_topline;
  136. # ifdef FEAT_DIFF
  137.     int        old_topfill;
  138. # endif
  139.     linenr_T    old_botline;
  140.     int        did_incsearch = FALSE;
  141.     int        incsearch_postponed = FALSE;
  142. #endif
  143.     int        did_wild_list = FALSE;    /* did wild_list() recently */
  144.     int        wim_index = 0;        /* index in wim_flags[] */
  145.     int        res;
  146.     int        save_msg_scroll = msg_scroll;
  147.     int        save_State = State;    /* remember State when called */
  148.     int        some_key_typed = FALSE;    /* one of the keys was typed */
  149. #ifdef FEAT_MOUSE
  150.     /* mouse drag and release events are ignored, unless they are
  151.      * preceded with a mouse down event */
  152.     int        ignore_drag_release = TRUE;
  153. #endif
  154. #ifdef FEAT_EVAL
  155.     int        break_ctrl_c = FALSE;
  156. #endif
  157.     expand_T    xpc;
  158.     long    *b_im_ptr = NULL;
  159.  
  160. #ifdef FEAT_SNIFF
  161.     want_sniff_request = 0;
  162. #endif
  163. #ifdef FEAT_EVAL
  164.     if (firstc == -1)
  165.     {
  166.     firstc = NUL;
  167.     break_ctrl_c = TRUE;
  168.     }
  169. #endif
  170. #ifdef FEAT_RIGHTLEFT
  171.     /* start without Hebrew mapping for a command line */
  172.     if (firstc == ':' || firstc == '=' || firstc == '>')
  173.     cmd_hkmap = 0;
  174. #endif
  175.  
  176.     ccline.overstrike = FALSE;            /* always start in insert mode */
  177. #ifdef FEAT_SEARCH_EXTRA
  178.     old_cursor = curwin->w_cursor;        /* needs to be restored later */
  179.     old_curswant = curwin->w_curswant;
  180.     old_leftcol = curwin->w_leftcol;
  181.     old_topline = curwin->w_topline;
  182. # ifdef FEAT_DIFF
  183.     old_topfill = curwin->w_topfill;
  184. # endif
  185.     old_botline = curwin->w_botline;
  186. #endif
  187.  
  188.     /*
  189.      * set some variables for redrawcmd()
  190.      */
  191.     ccline.cmdfirstc = (firstc == '@' ? 0 : firstc);
  192.     ccline.cmdindent = indent;
  193.     alloc_cmdbuff(exmode_active ? 250 : 0); /* alloc initial ccline.cmdbuff */
  194.     if (ccline.cmdbuff == NULL)
  195.     return NULL;                /* out of memory */
  196.     ccline.cmdlen = ccline.cmdpos = 0;
  197.     ccline.cmdbuff[0] = NUL;
  198.  
  199.     redir_off = TRUE;        /* don't redirect the typed command */
  200.     if (!cmd_silent)
  201.     {
  202.     i = msg_scrolled;
  203.     msg_scrolled = 0;        /* avoid wait_return message */
  204.     gotocmdline(TRUE);
  205.     msg_scrolled += i;
  206.     redrawcmdprompt();        /* draw prompt or indent */
  207.     set_cmdspos();
  208.     }
  209.     xpc.xp_context = EXPAND_NOTHING;
  210.  
  211.     /*
  212.      * Avoid scrolling when called by a recursive do_cmdline(), e.g. when
  213.      * doing ":@0" when register 0 doesn't contain a CR.
  214.      */
  215.     msg_scroll = FALSE;
  216.  
  217.     State = CMDLINE;
  218.  
  219.     if (firstc == '/' || firstc == '?' || firstc == '@')
  220.     {
  221.     /* Use ":lmap" mappings for search pattern and input(). */
  222.     if (curbuf->b_p_imsearch == B_IMODE_USE_INSERT)
  223.         b_im_ptr = &curbuf->b_p_iminsert;
  224.     else
  225.         b_im_ptr = &curbuf->b_p_imsearch;
  226.     if (*b_im_ptr == B_IMODE_LMAP)
  227.         State |= LANGMAP;
  228. #ifdef USE_IM_CONTROL
  229.     im_set_active(*b_im_ptr == B_IMODE_IM);
  230. #endif
  231.     }
  232. #ifdef USE_IM_CONTROL
  233.     else if (p_imcmdline)
  234.     im_set_active(TRUE);
  235. #endif
  236.  
  237. #ifdef FEAT_MOUSE
  238.     setmouse();
  239. #endif
  240. #ifdef CURSOR_SHAPE
  241.     ui_cursor_shape();        /* may show different cursor shape */
  242. #endif
  243.  
  244. #ifdef FEAT_CMDHIST
  245.     init_history();
  246.     hiscnt = hislen;        /* set hiscnt to impossible history value */
  247.     histype = hist_char2type(firstc);
  248. #endif
  249.  
  250. #ifdef FEAT_DIGRAPHS
  251.     do_digraph(-1);        /* init digraph typahead */
  252. #endif
  253.  
  254.     /*
  255.      * Collect the command string, handling editing keys.
  256.      */
  257.     for (;;)
  258.     {
  259. #ifdef USE_ON_FLY_SCROLL
  260.     dont_scroll = FALSE;    /* allow scrolling here */
  261. #endif
  262.     quit_more = FALSE;    /* reset after CTRL-D which had a more-prompt */
  263.  
  264.     cursorcmd();        /* set the cursor on the right spot */
  265.     c = safe_vgetc();
  266.     if (KeyTyped)
  267.     {
  268.         some_key_typed = TRUE;
  269. #ifdef FEAT_RIGHTLEFT
  270.         if (cmd_hkmap)
  271.         c = hkmap(c);
  272. # ifdef FEAT_FKMAP
  273.         if (cmd_fkmap)
  274.         c = cmdl_fkmap(c);
  275. # endif
  276. #endif
  277.     }
  278.  
  279.     /*
  280.      * Ignore got_int when CTRL-C was typed here.
  281.      * Don't ignore it in :global, we really need to break then, e.g., for
  282.      * ":g/pat/normal /pat" (without the <CR>).
  283.      * Don't ignore it for the input() function.
  284.      */
  285.     if ((c == Ctrl_C
  286. #ifdef UNIX
  287.         || c == intr_char
  288. #endif
  289.                 )
  290. #if defined(FEAT_EVAL) || defined(FEAT_CRYPT)
  291.         && firstc != '@'
  292. #endif
  293. #ifdef FEAT_EVAL
  294.         && !break_ctrl_c
  295. #endif
  296.         && !global_busy)
  297.         got_int = FALSE;
  298.  
  299. #ifdef FEAT_CMDHIST
  300.     /* free old command line when finished moving around in the history
  301.      * list */
  302.     if (lookfor != NULL
  303.         && c != K_S_DOWN && c != K_S_UP && c != K_DOWN && c != K_UP
  304.         && c != K_PAGEDOWN && c != K_PAGEUP
  305.         && c != K_KPAGEDOWN && c != K_KPAGEUP
  306.         && c != K_LEFT && c != K_RIGHT
  307.         && (cmd_numfiles > 0 || (c != Ctrl_P && c != Ctrl_N)))
  308.     {
  309.         vim_free(lookfor);
  310.         lookfor = NULL;
  311.     }
  312. #endif
  313.  
  314.     /*
  315.      * <S-Tab> works like CTRL-P (unless 'wc' is <S-Tab>).
  316.      */
  317.     if (c != p_wc && c == K_S_TAB && cmd_numfiles != -1)
  318.         c = Ctrl_P;
  319.  
  320. #ifdef FEAT_WILDMENU
  321.     /* Special translations for 'wildmenu' */
  322.     if (did_wild_list && p_wmnu)
  323.     {
  324.         if (c == K_LEFT)
  325.         c = Ctrl_P;
  326.         else if (c == K_RIGHT)
  327.         c = Ctrl_N;
  328.     }
  329.     /* Hitting CR after "emenu Name.": complete submenu */
  330.     if (xpc.xp_context == EXPAND_MENUNAMES && p_wmnu
  331.         && ccline.cmdpos > 1
  332.         && ccline.cmdbuff[ccline.cmdpos - 1] == '.'
  333.         && ccline.cmdbuff[ccline.cmdpos - 2] != '\\'
  334.         && (c == '\n' || c == '\r' || c == K_KENTER))
  335.         c = K_DOWN;
  336. #endif
  337.  
  338.     /* free expanded names when finished walking through matches */
  339.     if (cmd_numfiles != -1
  340.         && !(c == p_wc && KeyTyped) && c != p_wcm
  341.         && c != Ctrl_N && c != Ctrl_P && c != Ctrl_A
  342.         && c != Ctrl_L)
  343.     {
  344.         (void)ExpandOne(&xpc, NULL, NULL, 0, WILD_FREE);
  345.         did_wild_list = FALSE;
  346. #ifdef FEAT_WILDMENU
  347.         if (!p_wmnu || (c != K_UP && c != K_DOWN))
  348. #endif
  349.         xpc.xp_context = EXPAND_NOTHING;
  350.         wim_index = 0;
  351. #ifdef FEAT_WILDMENU
  352.         if (p_wmnu && wild_menu_showing)
  353.         {
  354.         int skt = KeyTyped;
  355.  
  356.         if (wild_menu_showing == WM_SCROLLED)
  357.         {
  358.             /* Entered command line, move it up */
  359.             cmdline_row--;
  360.             redrawcmd();
  361.         }
  362.         else if (save_p_ls != -1)
  363.         {
  364.             /* restore 'laststatus' if it was changed */
  365.             p_ls = save_p_ls;
  366.             last_status(FALSE);
  367.             update_screen(VALID);    /* redraw the screen NOW */
  368.             redrawcmd();
  369.             save_p_ls = -1;
  370.         }
  371.         else
  372.             win_redr_status(lastwin);
  373.         KeyTyped = skt;
  374.         wild_menu_showing = 0;
  375.         }
  376. #endif
  377.     }
  378.  
  379. #ifdef FEAT_WILDMENU
  380.     /* Special translations for 'wildmenu' */
  381.     if (xpc.xp_context == EXPAND_MENUNAMES && p_wmnu)
  382.     {
  383.         /* Hitting <Down> after "emenu Name.": complete submenu */
  384.         if (ccline.cmdbuff[ccline.cmdpos - 1] == '.' && c == K_DOWN)
  385.         c = p_wc;
  386.         else if (c == K_UP)
  387.         {
  388.         /* Hitting <Up>: Remove one submenu name in front of the
  389.          * cursor */
  390.         int found = FALSE;
  391.  
  392.         j = (int)(xpc.xp_pattern - ccline.cmdbuff);
  393.         i = 0;
  394.         while (--j > 0)
  395.         {
  396.             /* check for start of menu name */
  397.             if (ccline.cmdbuff[j] == ' '
  398.                 && ccline.cmdbuff[j - 1] != '\\')
  399.             {
  400.             i = j + 1;
  401.             break;
  402.             }
  403.             /* check for start of submenu name */
  404.             if (ccline.cmdbuff[j] == '.'
  405.                 && ccline.cmdbuff[j - 1] != '\\')
  406.             {
  407.             if (found)
  408.             {
  409.                 i = j + 1;
  410.                 break;
  411.             }
  412.             else
  413.                 found = TRUE;
  414.             }
  415.         }
  416.         if (i > 0)
  417.             cmdline_del(i);
  418.         c = p_wc;
  419.         xpc.xp_context = EXPAND_NOTHING;
  420.         }
  421.     }
  422.     if (xpc.xp_context == EXPAND_FILES && p_wmnu)
  423.     {
  424.         char_u upseg[5];
  425.  
  426.         upseg[0] = PATHSEP;
  427.         upseg[1] = '.';
  428.         upseg[2] = '.';
  429.         upseg[3] = PATHSEP;
  430.         upseg[4] = NUL;
  431.  
  432.         if (ccline.cmdbuff[ccline.cmdpos - 1] == PATHSEP
  433.             && c == K_DOWN
  434.             && (ccline.cmdbuff[ccline.cmdpos - 2] != '.'
  435.             || ccline.cmdbuff[ccline.cmdpos - 3] != '.'))
  436.         {
  437.         /* go down a directory */
  438.         c = p_wc;
  439.         }
  440.         else if (STRNCMP(xpc.xp_pattern, upseg + 1, 3) == 0 && c == K_DOWN)
  441.         {
  442.         /* If in a direct ancestor, strip off one ../ to go down */
  443.         int found = FALSE;
  444.  
  445.         j = ccline.cmdpos;
  446.         i = (int)(xpc.xp_pattern - ccline.cmdbuff);
  447.         while (--j > i)
  448.         {
  449.             if (vim_ispathsep(ccline.cmdbuff[j]))
  450.             {
  451.             found = TRUE;
  452.             break;
  453.             }
  454.         }
  455.         if (found
  456.             && ccline.cmdbuff[j - 1] == '.'
  457.             && ccline.cmdbuff[j - 2] == '.'
  458.             && (vim_ispathsep(ccline.cmdbuff[j - 3]) || j == i + 2))
  459.         {
  460.             cmdline_del(j - 2);
  461.             c = p_wc;
  462.         }
  463.         }
  464.         else if (c == K_UP)
  465.         {
  466.         /* go up a directory */
  467.         int found = FALSE;
  468.  
  469.         j = ccline.cmdpos - 1;
  470.         i = (int)(xpc.xp_pattern - ccline.cmdbuff);
  471.         while (--j > i)
  472.         {
  473. #ifdef FEAT_MBYTE
  474.             if (has_mbyte)
  475.             j -= (*mb_head_off)(ccline.cmdbuff, ccline.cmdbuff + j);
  476. #endif
  477.             if (vim_ispathsep(ccline.cmdbuff[j])
  478. #ifdef BACKSLASH_IN_FILENAME
  479.                 && vim_strchr(" *?[{`$%#", ccline.cmdbuff[j + 1])
  480.                    == NULL
  481. #endif
  482.                )
  483.             {
  484.             if (found)
  485.             {
  486.                 i = j + 1;
  487.                 break;
  488.             }
  489.             else
  490.                 found = TRUE;
  491.             }
  492.         }
  493.  
  494.         if (!found)
  495.             j = i;
  496.         else if (STRNCMP(ccline.cmdbuff + j, upseg, 4) == 0)
  497.             j += 4;
  498.         else if (STRNCMP(ccline.cmdbuff + j, upseg + 1, 3) == 0
  499.                  && j == i)
  500.             j += 3;
  501.         else
  502.             j = 0;
  503.         if (j > 0)
  504.         {
  505.             /* TODO this is only for DOS/UNIX systems - need to put in
  506.              * machine-specific stuff here and in upseg init */
  507.             cmdline_del(j);
  508.             put_on_cmdline(upseg + 1, 3, FALSE);
  509.         }
  510.         else if (ccline.cmdpos > i)
  511.             cmdline_del(i);
  512.         c = p_wc;
  513.         }
  514.     }
  515. #if 0 /* If enabled <Down> on a file takes you _completely_ out of wildmenu */
  516.     if (p_wmnu
  517.         && (xpc.xp_context == EXPAND_FILES
  518.             || xpc.xp_context == EXPAND_MENUNAMES)
  519.         && (c == K_UP || c == K_DOWN))
  520.         xpc.xp_context = EXPAND_NOTHING;
  521. #endif
  522.  
  523. #endif    /* FEAT_WILDMENU */
  524.  
  525.     /* CTRL-\ CTRL-N goes to Normal mode */
  526.     if (c == Ctrl_BSL)
  527.     {
  528.         ++no_mapping;
  529.         ++allow_keys;
  530.         c = safe_vgetc();
  531.         --no_mapping;
  532.         --allow_keys;
  533.         if (c != Ctrl_N)
  534.         {
  535.         vungetc(c);
  536.         c = Ctrl_BSL;
  537.         }
  538.         else
  539.         {
  540.         gotesc = TRUE;    /* will free ccline.cmdbuff after putting it
  541.                    in history */
  542.         goto returncmd;    /* back to Normal mode */
  543.         }
  544.     }
  545.  
  546. #ifdef FEAT_CMDWIN
  547.     if (c == cedit_key || c == K_CMDWIN)
  548.     {
  549.         /*
  550.          * Open a window to edit the command line (and history).
  551.          */
  552.         c = ex_window();
  553.         some_key_typed = TRUE;
  554.     }
  555. # ifdef FEAT_DIGRAPHS
  556.     else
  557. # endif
  558. #endif
  559. #ifdef FEAT_DIGRAPHS
  560.         c = do_digraph(c);
  561. #endif
  562.  
  563.     if (c == '\n' || c == '\r' || c == K_KENTER || (c == ESC
  564.             && (!KeyTyped || vim_strchr(p_cpo, CPO_ESC) != NULL)))
  565.     {
  566.         gotesc = FALSE;    /* Might have typed ESC previously, don't
  567.                    truncate the cmdline now. */
  568.         if (ccheck_abbr(c + ABBR_OFF))
  569.         goto cmdline_changed;
  570.         if (!cmd_silent)
  571.         {
  572.         windgoto(msg_row, 0);
  573.         out_flush();
  574.         }
  575.         break;
  576.     }
  577.  
  578.     /*
  579.      * Completion for 'wildchar' or 'wildcharm' key.
  580.      * - hitting <ESC> twice means: abandon command line.
  581.      * - wildcard expansion is only done when the 'wildchar' key is really
  582.      *   typed, not when it comes from a macro
  583.      */
  584.     if ((c == p_wc && !gotesc && KeyTyped) || c == p_wcm)
  585.     {
  586.         if (cmd_numfiles > 0)   /* typed p_wc at least twice */
  587.         {
  588.         /* if 'wildmode' contains "list" may still need to list */
  589.         if (cmd_numfiles > 1
  590.             && !did_wild_list
  591.             && (wim_flags[wim_index] & WIM_LIST))
  592.         {
  593.             (void)showmatches(&xpc, FALSE);
  594.             redrawcmd();
  595.             did_wild_list = TRUE;
  596.         }
  597.         if (wim_flags[wim_index] & WIM_LONGEST)
  598.             res = nextwild(&xpc, WILD_LONGEST, WILD_NO_BEEP);
  599.         else if (wim_flags[wim_index] & WIM_FULL)
  600.             res = nextwild(&xpc, WILD_NEXT, WILD_NO_BEEP);
  601.         else
  602.             res = OK;        /* don't insert 'wildchar' now */
  603.         }
  604.         else            /* typed p_wc first time */
  605.         {
  606.         wim_index = 0;
  607.         j = ccline.cmdpos;
  608.         /* if 'wildmode' first contains "longest", get longest
  609.          * common part */
  610.         if (wim_flags[0] & WIM_LONGEST)
  611.             res = nextwild(&xpc, WILD_LONGEST, WILD_NO_BEEP);
  612.         else
  613.             res = nextwild(&xpc, WILD_EXPAND_KEEP, WILD_NO_BEEP);
  614.  
  615.         /* if interrupted while completing, behave like it failed */
  616.         if (got_int)
  617.         {
  618.             (void)vpeekc();    /* remove <C-C> from input stream */
  619.             got_int = FALSE;    /* don't abandon the command line */
  620.             (void)ExpandOne(&xpc, NULL, NULL, 0, WILD_FREE);
  621. #ifdef FEAT_WILDMENU
  622.             xpc.xp_context = EXPAND_NOTHING;
  623. #endif
  624.             goto cmdline_changed;
  625.         }
  626.  
  627.         /* when more than one match, and 'wildmode' first contains
  628.          * "list", or no change and 'wildmode' contains "longest,list",
  629.          * list all matches */
  630.         if (res == OK && cmd_numfiles > 1)
  631.         {
  632.             /* a "longest" that didn't do anything is skipped (but not
  633.              * "list:longest") */
  634.             if (wim_flags[0] == WIM_LONGEST && ccline.cmdpos == j)
  635.             wim_index = 1;
  636.             if ((wim_flags[wim_index] & WIM_LIST)
  637. #ifdef FEAT_WILDMENU
  638.                 || (p_wmnu && (wim_flags[wim_index] & WIM_FULL) != 0)
  639. #endif
  640.                 )
  641.             {
  642.             if (!(wim_flags[0] & WIM_LONGEST))
  643.             {
  644. #ifdef FEAT_WILDMENU
  645.                 int p_wmnu_save = p_wmnu;
  646.                 p_wmnu = 0;
  647. #endif
  648.                 nextwild(&xpc, WILD_PREV, 0); /* remove match */
  649. #ifdef FEAT_WILDMENU
  650.                 p_wmnu = p_wmnu_save;
  651. #endif
  652.             }
  653. #ifdef FEAT_WILDMENU
  654.             (void)showmatches(&xpc, p_wmnu
  655.                 && ((wim_flags[wim_index] & WIM_LIST) == 0));
  656. #else
  657.             (void)showmatches(&xpc, FALSE);
  658. #endif
  659.             redrawcmd();
  660.             did_wild_list = TRUE;
  661.             if (wim_flags[wim_index] & WIM_LONGEST)
  662.                 nextwild(&xpc, WILD_LONGEST, WILD_NO_BEEP);
  663.             else if (wim_flags[wim_index] & WIM_FULL)
  664.                 nextwild(&xpc, WILD_NEXT, WILD_NO_BEEP);
  665.             }
  666.             else
  667.             vim_beep();
  668.         }
  669. #ifdef FEAT_WILDMENU
  670.         else if (cmd_numfiles == -1)
  671.             xpc.xp_context = EXPAND_NOTHING;
  672. #endif
  673.         }
  674.         if (wim_index < 3)
  675.         ++wim_index;
  676.         if (c == ESC)
  677.         gotesc = TRUE;
  678.         if (res == OK)
  679.         goto cmdline_changed;
  680.     }
  681.  
  682.     gotesc = FALSE;
  683.  
  684.     /* <S-Tab> goes to last match, in a clumsy way */
  685.     if (c == K_S_TAB && KeyTyped)
  686.     {
  687.         if (nextwild(&xpc, WILD_EXPAND_KEEP, 0) == OK
  688.             && nextwild(&xpc, WILD_PREV, 0) == OK
  689.             && nextwild(&xpc, WILD_PREV, 0) == OK)
  690.         goto cmdline_changed;
  691.     }
  692.  
  693.     if (c == NUL || c == K_ZERO)        /* NUL is stored as NL */
  694.         c = NL;
  695.  
  696.     do_abbr = TRUE;        /* default: check for abbreviation */
  697.  
  698.     /*
  699.      * Big switch for a typed command line character.
  700.      */
  701.     switch (c)
  702.     {
  703.     case K_BS:
  704.     case Ctrl_H:
  705.     case K_DEL:
  706.     case K_KDEL:
  707.     case Ctrl_W:
  708. #ifdef FEAT_FKMAP
  709.         if (cmd_fkmap && c == K_BS)
  710.             c = K_DEL;
  711. #endif
  712.         if (c == K_KDEL)
  713.             c = K_DEL;
  714.  
  715.         /*
  716.          * delete current character is the same as backspace on next
  717.          * character, except at end of line
  718.          */
  719.         if (c == K_DEL && ccline.cmdpos != ccline.cmdlen)
  720.             ++ccline.cmdpos;
  721. #ifdef FEAT_MBYTE
  722.         if (has_mbyte && c == K_DEL)
  723.             ccline.cmdpos += mb_off_next(ccline.cmdbuff,
  724.                           ccline.cmdbuff + ccline.cmdpos);
  725. #endif
  726.         if (ccline.cmdpos > 0)
  727.         {
  728.             char_u *p;
  729.  
  730.             j = ccline.cmdpos;
  731.             p = ccline.cmdbuff + j;
  732. #ifdef FEAT_MBYTE
  733.             if (has_mbyte)
  734.             {
  735.             p = mb_prevptr(ccline.cmdbuff, p);
  736.             if (c == Ctrl_W)
  737.             {
  738.                 while (p > ccline.cmdbuff && vim_isspace(*p))
  739.                 p = mb_prevptr(ccline.cmdbuff, p);
  740.                 i = mb_get_class(p);
  741.                 while (p > ccline.cmdbuff && mb_get_class(p) == i)
  742.                 p = mb_prevptr(ccline.cmdbuff, p);
  743.                 if (mb_get_class(p) != i)
  744.                 p += (*mb_ptr2len_check)(p);
  745.             }
  746.             }
  747.             else
  748. #endif
  749.             if (c == Ctrl_W)
  750.             {
  751.             while (p > ccline.cmdbuff && vim_isspace(p[-1]))
  752.                 --p;
  753.             i = vim_iswordc(p[-1]);
  754.             while (p > ccline.cmdbuff && !vim_isspace(p[-1])
  755.                 && vim_iswordc(p[-1]) == i)
  756.                 --p;
  757.             }
  758.             else
  759.             --p;
  760.             ccline.cmdpos = (int)(p - ccline.cmdbuff);
  761.             ccline.cmdlen -= j - ccline.cmdpos;
  762.             i = ccline.cmdpos;
  763.             while (i < ccline.cmdlen)
  764.             ccline.cmdbuff[i++] = ccline.cmdbuff[j++];
  765.  
  766.             /* Truncate at the end, required for multi-byte chars. */
  767.             ccline.cmdbuff[ccline.cmdlen] = NUL;
  768.             redrawcmd();
  769.         }
  770.         else if (ccline.cmdlen == 0 && c != Ctrl_W
  771.                    && ccline.cmdprompt == NULL && indent == 0)
  772.         {
  773.             /* In ex and debug mode it doesn't make sense to return. */
  774.             if (exmode_active
  775. #ifdef FEAT_EVAL
  776.                 || ccline.cmdfirstc == '>'
  777. #endif
  778.                 )
  779.             goto cmdline_not_changed;
  780.  
  781.             vim_free(ccline.cmdbuff);    /* no commandline to return */
  782.             ccline.cmdbuff = NULL;
  783.             if (!cmd_silent)
  784.             {
  785.             msg_col = 0;
  786.             msg_putchar(' ');        /* delete ':' */
  787.             }
  788.             redraw_cmdline = TRUE;
  789.             goto returncmd;        /* back to cmd mode */
  790.         }
  791.         goto cmdline_changed;
  792.  
  793.     case K_INS:
  794.     case K_KINS:
  795. #ifdef FEAT_FKMAP
  796.         /* if Farsi mode set, we are in reverse insert mode -
  797.            Do not change the mode */
  798.         if (cmd_fkmap)
  799.             beep_flush();
  800.         else
  801. #endif
  802.         ccline.overstrike = !ccline.overstrike;
  803. #ifdef CURSOR_SHAPE
  804.         ui_cursor_shape();    /* may show different cursor shape */
  805. #endif
  806.         goto cmdline_not_changed;
  807.  
  808.     case Ctrl_HAT:
  809.         if (map_to_exists_mode((char_u *)"", LANGMAP))
  810.         {
  811.             /* ":lmap" mappings exists, toggle use of mappings. */
  812.             State ^= LANGMAP;
  813. #ifdef USE_IM_CONTROL
  814.             im_set_active(FALSE);    /* Disable input method */
  815. #endif
  816.             if (b_im_ptr != NULL)
  817.             {
  818.             if (State & LANGMAP)
  819.                 *b_im_ptr = B_IMODE_LMAP;
  820.             else
  821.                 *b_im_ptr = B_IMODE_NONE;
  822.             }
  823.         }
  824. #ifdef USE_IM_CONTROL
  825.         else
  826.         {
  827.             /* There are no ":lmap" mappings, toggle IM.  When
  828.              * 'imdisable' is set don't try getting the status, it's
  829.              * always off. */
  830.             if ((p_imdisable && b_im_ptr != NULL)
  831.                 ? *b_im_ptr == B_IMODE_IM : im_get_status())
  832.             {
  833.             im_set_active(FALSE);    /* Disable input method */
  834.             if (b_im_ptr != NULL)
  835.                 *b_im_ptr = B_IMODE_NONE;
  836.             }
  837.             else
  838.             {
  839.             im_set_active(TRUE);    /* Enable input method */
  840.             if (b_im_ptr != NULL)
  841.                 *b_im_ptr = B_IMODE_IM;
  842.             }
  843.         }
  844. #endif
  845.         if (b_im_ptr != NULL)
  846.         {
  847.             if (b_im_ptr == &curbuf->b_p_iminsert)
  848.             set_iminsert_global();
  849.             else
  850.             set_imsearch_global();
  851.         }
  852. #ifdef CURSOR_SHAPE
  853.         ui_cursor_shape();    /* may show different cursor shape */
  854. #endif
  855.         goto cmdline_not_changed;
  856.  
  857. /*    case '@':   only in very old vi */
  858.     case Ctrl_U:
  859.         /* delete all characters left of the cursor */
  860.         j = ccline.cmdpos;
  861.         ccline.cmdlen -= j;
  862.         i = ccline.cmdpos = 0;
  863.         while (i < ccline.cmdlen)
  864.             ccline.cmdbuff[i++] = ccline.cmdbuff[j++];
  865.         /* Truncate at the end, required for multi-byte chars. */
  866.         ccline.cmdbuff[ccline.cmdlen] = NUL;
  867.         redrawcmd();
  868.         goto cmdline_changed;
  869.  
  870. #ifdef FEAT_CLIPBOARD
  871.     case Ctrl_Y:
  872.         /* Copy the modeless selection, if there is one. */
  873.         if (clip_star.state != SELECT_CLEARED)
  874.         {
  875.             if (clip_star.state == SELECT_DONE)
  876.             clip_copy_modeless_selection(TRUE);
  877.             goto cmdline_not_changed;
  878.         }
  879.         break;
  880. #endif
  881.  
  882.     case ESC:    /* get here if p_wc != ESC or when ESC typed twice */
  883.     case Ctrl_C:
  884.         /* In exmode it doesn't make sense to return. */
  885.         if (exmode_active)
  886.             goto cmdline_not_changed;
  887.  
  888.         gotesc = TRUE;        /* will free ccline.cmdbuff after
  889.                        putting it in history */
  890.         goto returncmd;        /* back to cmd mode */
  891.  
  892.     case Ctrl_R:            /* insert register */
  893. #ifdef USE_ON_FLY_SCROLL
  894.         dont_scroll = TRUE;    /* disallow scrolling here */
  895. #endif
  896.         putcmdline('"', TRUE);
  897.         ++no_mapping;
  898.         i = c = safe_vgetc();    /* CTRL-R <char> */
  899.         if (i == Ctrl_O)
  900.             i = Ctrl_R;        /* CTRL-R CTRL-O == CTRL-R CTRL-R */
  901.         if (i == Ctrl_R)
  902.             c = safe_vgetc();    /* CTRL-R CTRL-R <char> */
  903.         --no_mapping;
  904. #ifdef FEAT_EVAL
  905.         /*
  906.          * Insert the result of an expression.
  907.          * Need to save the current command line, to be able to enter
  908.          * a new one...
  909.          */
  910.         if (c == '=')
  911.         {
  912.             struct cmdline_info        save_ccline;
  913.  
  914.             if (ccline.cmdfirstc == '=')/* can't do this recursively */
  915.             {
  916.             beep_flush();
  917.             c = ESC;
  918.             }
  919.             else
  920.             {
  921.             save_ccline = ccline;
  922.             ccline.cmdbuff = NULL;
  923.             ccline.cmdprompt = NULL;
  924.             c = get_expr_register();
  925.             ccline = save_ccline;
  926.             }
  927.         }
  928. #endif
  929.         if (c != ESC)        /* use ESC to cancel inserting register */
  930.         {
  931.             cmdline_paste(c, i == Ctrl_R);
  932.             KeyTyped = FALSE;    /* Don't do p_wc completion. */
  933.         }
  934.         redrawcmd();
  935.         goto cmdline_changed;
  936.  
  937.     case Ctrl_D:
  938.         if (showmatches(&xpc, FALSE) == EXPAND_NOTHING)
  939.             break;    /* Use ^D as normal char instead */
  940.  
  941.         redrawcmd();
  942.         continue;    /* don't do incremental search now */
  943.  
  944.     case K_RIGHT:
  945.     case K_S_RIGHT:
  946.     case K_C_RIGHT:
  947.         do
  948.         {
  949.             if (ccline.cmdpos >= ccline.cmdlen)
  950.             break;
  951.             i = cmdline_charsize(ccline.cmdpos);
  952.             if (KeyTyped && ccline.cmdspos + i >= Columns * Rows)
  953.             break;
  954.             ccline.cmdspos += i;
  955. #ifdef FEAT_MBYTE
  956.             if (has_mbyte)
  957.             ccline.cmdpos += (*mb_ptr2len_check)(ccline.cmdbuff
  958.                                  + ccline.cmdpos);
  959.             else
  960. #endif
  961.             ++ccline.cmdpos;
  962.         }
  963.         while ((c == K_S_RIGHT || c == K_C_RIGHT)
  964.             && ccline.cmdbuff[ccline.cmdpos] != ' ');
  965. #ifdef FEAT_MBYTE
  966.         if (has_mbyte)
  967.             set_cmdspos_cursor();
  968. #endif
  969.         goto cmdline_not_changed;
  970.  
  971.     case K_LEFT:
  972.     case K_S_LEFT:
  973.     case K_C_LEFT:
  974.         do
  975.         {
  976.             if (ccline.cmdpos == 0)
  977.             break;
  978.             --ccline.cmdpos;
  979. #ifdef FEAT_MBYTE
  980.             if (has_mbyte)    /* move to first byte of char */
  981.             ccline.cmdpos -= (*mb_head_off)(ccline.cmdbuff,
  982.                           ccline.cmdbuff + ccline.cmdpos);
  983. #endif
  984.             ccline.cmdspos -= cmdline_charsize(ccline.cmdpos);
  985.         }
  986.         while ((c == K_S_LEFT || c == K_C_LEFT)
  987.             && ccline.cmdbuff[ccline.cmdpos - 1] != ' ');
  988. #ifdef FEAT_MBYTE
  989.         if (has_mbyte)
  990.             set_cmdspos_cursor();
  991. #endif
  992.         goto cmdline_not_changed;
  993.  
  994.     case K_IGNORE:
  995.         goto cmdline_not_changed;    /* Ignore mouse */
  996.  
  997. #ifdef FEAT_MOUSE
  998.     case K_MIDDLEDRAG:
  999.     case K_MIDDLERELEASE:
  1000.         goto cmdline_not_changed;    /* Ignore mouse */
  1001.  
  1002.     case K_MIDDLEMOUSE:
  1003. # ifdef FEAT_GUI
  1004.         /* When GUI is active, also paste when 'mouse' is empty */
  1005.         if (!gui.in_use)
  1006. # endif
  1007.             if (!mouse_has(MOUSE_COMMAND))
  1008.             goto cmdline_not_changed;   /* Ignore mouse */
  1009. #ifdef FEAT_CLIPBOARD
  1010.         if (clip_star.available)
  1011.             cmdline_paste('*', TRUE);
  1012.         else
  1013. #endif
  1014.             cmdline_paste(0, TRUE);
  1015.         redrawcmd();
  1016.         goto cmdline_changed;
  1017.  
  1018.     case K_LEFTDRAG:
  1019.     case K_LEFTRELEASE:
  1020.     case K_RIGHTDRAG:
  1021.     case K_RIGHTRELEASE:
  1022.         /* Ignore drag and release events when the button-down wasn't
  1023.          * seen before. */
  1024.         if (ignore_drag_release)
  1025.             goto cmdline_not_changed;
  1026.         /* FALLTHROUGH */
  1027.     case K_LEFTMOUSE:
  1028.     case K_RIGHTMOUSE:
  1029.         if (c == K_LEFTRELEASE || c == K_RIGHTRELEASE)
  1030.             ignore_drag_release = TRUE;
  1031.         else
  1032.             ignore_drag_release = FALSE;
  1033. # ifdef FEAT_GUI
  1034.         /* When GUI is active, also move when 'mouse' is empty */
  1035.         if (!gui.in_use)
  1036. # endif
  1037.             if (!mouse_has(MOUSE_COMMAND))
  1038.             goto cmdline_not_changed;   /* Ignore mouse */
  1039. # ifdef FEAT_CLIPBOARD
  1040.         if (mouse_row < cmdline_row && clip_star.available)
  1041.         {
  1042.             int        button, is_click, is_drag;
  1043.  
  1044.             /*
  1045.              * Handle modeless selection.
  1046.              */
  1047.             button = get_mouse_button(KEY2TERMCAP1(c),
  1048.                              &is_click, &is_drag);
  1049.             if (mouse_model_popup() && button == MOUSE_LEFT
  1050.                            && (mod_mask & MOD_MASK_SHIFT))
  1051.             {
  1052.             /* Translate shift-left to right button. */
  1053.             button = MOUSE_RIGHT;
  1054.             mod_mask &= ~MOD_MASK_SHIFT;
  1055.             }
  1056.             clip_modeless(button, is_click, is_drag);
  1057.             goto cmdline_not_changed;
  1058.         }
  1059. # endif
  1060.  
  1061.         set_cmdspos();
  1062.         for (ccline.cmdpos = 0; ccline.cmdpos < ccline.cmdlen;
  1063.                                   ++ccline.cmdpos)
  1064.         {
  1065.             i = cmdline_charsize(ccline.cmdpos);
  1066.             if (mouse_row <= cmdline_row + ccline.cmdspos / Columns
  1067.                   && mouse_col < ccline.cmdspos % Columns + i)
  1068.             break;
  1069. #ifdef FEAT_MBYTE
  1070.             if (has_mbyte)
  1071.             {
  1072.             /* Count ">" for double-wide char that doesn't fit. */
  1073.             if ((*mb_ptr2cells)(ccline.cmdbuff + ccline.cmdpos) > 1
  1074.                     && ccline.cmdspos % Columns + i > Columns)
  1075.                 ccline.cmdspos++;
  1076.             ccline.cmdpos += (*mb_ptr2len_check)(ccline.cmdbuff
  1077.                              + ccline.cmdpos) - 1;
  1078.             }
  1079. #endif
  1080.             ccline.cmdspos += i;
  1081.         }
  1082.         goto cmdline_not_changed;
  1083.  
  1084.     /* Mouse scroll wheel: ignored here */
  1085.     case K_MOUSEDOWN:
  1086.     case K_MOUSEUP:
  1087.         goto cmdline_not_changed;
  1088.  
  1089. #endif    /* FEAT_MOUSE */
  1090.  
  1091. #ifdef FEAT_GUI
  1092.     case K_LEFTMOUSE_NM:    /* mousefocus click, ignored */
  1093.     case K_LEFTRELEASE_NM:
  1094.         goto cmdline_not_changed;
  1095.  
  1096.     case K_VER_SCROLLBAR:
  1097.         if (!msg_scrolled)
  1098.         {
  1099.             gui_do_scroll();
  1100.             redrawcmd();
  1101.         }
  1102.         goto cmdline_not_changed;
  1103.  
  1104.     case K_HOR_SCROLLBAR:
  1105.         if (!msg_scrolled)
  1106.         {
  1107.             gui_do_horiz_scroll();
  1108.             redrawcmd();
  1109.         }
  1110.         goto cmdline_not_changed;
  1111. #endif
  1112.     case K_SELECT:        /* end of Select mode mapping - ignore */
  1113.         goto cmdline_not_changed;
  1114.  
  1115.     case Ctrl_B:        /* begin of command line */
  1116.     case K_HOME:
  1117.     case K_KHOME:
  1118.     case K_XHOME:
  1119.     case K_S_HOME:
  1120.     case K_C_HOME:
  1121.         ccline.cmdpos = 0;
  1122.         set_cmdspos();
  1123.         goto cmdline_not_changed;
  1124.  
  1125.     case Ctrl_E:        /* end of command line */
  1126.     case K_END:
  1127.     case K_KEND:
  1128.     case K_XEND:
  1129.     case K_S_END:
  1130.     case K_C_END:
  1131.         ccline.cmdpos = ccline.cmdlen;
  1132.         set_cmdspos_cursor();
  1133.         goto cmdline_not_changed;
  1134.  
  1135.     case Ctrl_A:        /* all matches */
  1136.         if (nextwild(&xpc, WILD_ALL, 0) == FAIL)
  1137.             break;
  1138.         goto cmdline_changed;
  1139.  
  1140.     case Ctrl_L:        /* longest common part */
  1141.         if (nextwild(&xpc, WILD_LONGEST, 0) == FAIL)
  1142.             break;
  1143.         goto cmdline_changed;
  1144.  
  1145.     case Ctrl_N:        /* next match */
  1146.     case Ctrl_P:        /* previous match */
  1147.         if (cmd_numfiles > 0)
  1148.         {
  1149.             if (nextwild(&xpc, (c == Ctrl_P) ? WILD_PREV : WILD_NEXT, 0)
  1150.                                       == FAIL)
  1151.             break;
  1152.             goto cmdline_changed;
  1153.         }
  1154.  
  1155. #ifdef FEAT_CMDHIST
  1156.     case K_UP:
  1157.     case K_DOWN:
  1158.     case K_S_UP:
  1159.     case K_S_DOWN:
  1160.     case K_PAGEUP:
  1161.     case K_KPAGEUP:
  1162.     case K_PAGEDOWN:
  1163.     case K_KPAGEDOWN:
  1164.         if (hislen == 0 || firstc == NUL)    /* no history */
  1165.             goto cmdline_not_changed;
  1166.  
  1167.         i = hiscnt;
  1168.  
  1169.         /* save current command string so it can be restored later */
  1170.         if (lookfor == NULL)
  1171.         {
  1172.             if ((lookfor = vim_strsave(ccline.cmdbuff)) == NULL)
  1173.             goto cmdline_not_changed;
  1174.             lookfor[ccline.cmdpos] = NUL;
  1175.         }
  1176.  
  1177.         j = (int)STRLEN(lookfor);
  1178.         for (;;)
  1179.         {
  1180.             /* one step backwards */
  1181.             if (c == K_UP || c == K_S_UP || c == Ctrl_P ||
  1182.                 c == K_PAGEUP || c == K_KPAGEUP)
  1183.             {
  1184.             if (hiscnt == hislen)    /* first time */
  1185.                 hiscnt = hisidx[histype];
  1186.             else if (hiscnt == 0 && hisidx[histype] != hislen - 1)
  1187.                 hiscnt = hislen - 1;
  1188.             else if (hiscnt != hisidx[histype] + 1)
  1189.                 --hiscnt;
  1190.             else            /* at top of list */
  1191.             {
  1192.                 hiscnt = i;
  1193.                 break;
  1194.             }
  1195.             }
  1196.             else    /* one step forwards */
  1197.             {
  1198.             /* on last entry, clear the line */
  1199.             if (hiscnt == hisidx[histype])
  1200.             {
  1201.                 hiscnt = hislen;
  1202.                 break;
  1203.             }
  1204.  
  1205.             /* not on a history line, nothing to do */
  1206.             if (hiscnt == hislen)
  1207.                 break;
  1208.             if (hiscnt == hislen - 1)   /* wrap around */
  1209.                 hiscnt = 0;
  1210.             else
  1211.                 ++hiscnt;
  1212.             }
  1213.             if (hiscnt < 0 || history[histype][hiscnt].hisstr == NULL)
  1214.             {
  1215.             hiscnt = i;
  1216.             break;
  1217.             }
  1218.             if ((c != K_UP && c != K_DOWN) || hiscnt == i ||
  1219.                 STRNCMP(history[histype][hiscnt].hisstr,
  1220.                             lookfor, (size_t)j) == 0)
  1221.             break;
  1222.         }
  1223.  
  1224.         if (hiscnt != i)    /* jumped to other entry */
  1225.         {
  1226.             char_u    *p;
  1227.  
  1228.             vim_free(ccline.cmdbuff);
  1229.             if (hiscnt == hislen)
  1230.             p = lookfor;    /* back to the old one */
  1231.             else
  1232.             p = history[histype][hiscnt].hisstr;
  1233.  
  1234.             alloc_cmdbuff((int)STRLEN(p));
  1235.             if (ccline.cmdbuff == NULL)
  1236.             goto returncmd;
  1237.             STRCPY(ccline.cmdbuff, p);
  1238.  
  1239.             ccline.cmdpos = ccline.cmdlen = (int)STRLEN(ccline.cmdbuff);
  1240.             redrawcmd();
  1241.             goto cmdline_changed;
  1242.         }
  1243.         beep_flush();
  1244.         goto cmdline_not_changed;
  1245. #endif
  1246.  
  1247.     case Ctrl_V:
  1248.     case Ctrl_Q:
  1249. #ifdef FEAT_MOUSE
  1250.         ignore_drag_release = TRUE;
  1251. #endif
  1252.         putcmdline('^', TRUE);
  1253.         c = get_literal();        /* get next (two) character(s) */
  1254.         do_abbr = FALSE;        /* don't do abbreviation now */
  1255.         break;
  1256.  
  1257. #ifdef FEAT_DIGRAPHS
  1258.     case Ctrl_K:
  1259. #ifdef FEAT_MOUSE
  1260.         ignore_drag_release = TRUE;
  1261. #endif
  1262.         putcmdline('?', TRUE);
  1263. #ifdef USE_ON_FLY_SCROLL
  1264.         dont_scroll = TRUE;        /* disallow scrolling here */
  1265. #endif
  1266.         c = get_digraph(TRUE);
  1267.         if (c != NUL)
  1268.             break;
  1269.  
  1270.         redrawcmd();
  1271.         goto cmdline_not_changed;
  1272. #endif /* FEAT_DIGRAPHS */
  1273.  
  1274. #ifdef FEAT_RIGHTLEFT
  1275.     case Ctrl__:        /* CTRL-_: switch language mode */
  1276.         if (!p_ari)
  1277.             break;
  1278. #ifdef FEAT_FKMAP
  1279.         if (p_altkeymap)
  1280.         {
  1281.             cmd_fkmap = !cmd_fkmap;
  1282.             if (cmd_fkmap)    /* in Farsi always in Insert mode */
  1283.             ccline.overstrike = FALSE;
  1284.         }
  1285.         else                /* Hebrew is default */
  1286. #endif
  1287.             cmd_hkmap = !cmd_hkmap;
  1288.         goto cmdline_not_changed;
  1289. #endif
  1290.  
  1291.     default:
  1292. #ifdef UNIX
  1293.         if (c == intr_char)
  1294.         {
  1295.             gotesc = TRUE;    /* will free ccline.cmdbuff after
  1296.                        putting it in history */
  1297.             goto returncmd;    /* back to Normal mode */
  1298.         }
  1299. #endif
  1300.         /*
  1301.          * Normal character with no special meaning.  Just set mod_mask
  1302.          * to 0x0 so that typing Shift-Space in the GUI doesn't enter
  1303.          * the string <S-Space>.  This should only happen after ^V.
  1304.          */
  1305.         if (!IS_SPECIAL(c))
  1306.             mod_mask = 0x0;
  1307.         break;
  1308.     }
  1309.     /*
  1310.      * End of switch on command line character.
  1311.      * We come here if we have a normal character.
  1312.      */
  1313.  
  1314.     if (do_abbr && (IS_SPECIAL(c) || !vim_iswordc(c)) && ccheck_abbr(c))
  1315.         goto cmdline_changed;
  1316.  
  1317.     /*
  1318.      * put the character in the command line
  1319.      */
  1320.     if (IS_SPECIAL(c) || mod_mask != 0)
  1321.         put_on_cmdline(get_special_key_name(c, mod_mask), -1, TRUE);
  1322.     else
  1323.     {
  1324. #ifdef FEAT_MBYTE
  1325.         if (has_mbyte)
  1326.         {
  1327.         j = (*mb_char2bytes)(c, IObuff);
  1328.         put_on_cmdline(IObuff, j, TRUE);
  1329.         }
  1330.         else
  1331. #endif
  1332.         {
  1333.         IObuff[0] = c;
  1334.         put_on_cmdline(IObuff, 1, TRUE);
  1335.         }
  1336.     }
  1337.     goto cmdline_changed;
  1338.  
  1339. /*
  1340.  * This part implements incremental searches for "/" and "?"
  1341.  * Jump to cmdline_not_changed when a character has been read but the command
  1342.  * line did not change. Then we only search and redraw if something changed in
  1343.  * the past.
  1344.  * Jump to cmdline_changed when the command line did change.
  1345.  * (Sorry for the goto's, I know it is ugly).
  1346.  */
  1347. cmdline_not_changed:
  1348. #ifdef FEAT_SEARCH_EXTRA
  1349.     if (!incsearch_postponed)
  1350.         continue;
  1351. #endif
  1352.  
  1353. cmdline_changed:
  1354. #ifdef FEAT_SEARCH_EXTRA
  1355.     /*
  1356.      * 'incsearch' highlighting.
  1357.      */
  1358.     if (p_is && !cmd_silent && (firstc == '/' || firstc == '?'))
  1359.     {
  1360.         /* if there is a character waiting, search and redraw later */
  1361.         if (char_avail())
  1362.         {
  1363.         incsearch_postponed = TRUE;
  1364.         continue;
  1365.         }
  1366.         incsearch_postponed = FALSE;
  1367.         curwin->w_cursor = old_cursor;  /* start at old position */
  1368.  
  1369.         /* If there is no command line, don't do anything */
  1370.         if (ccline.cmdlen == 0)
  1371.         i = 0;
  1372.         else
  1373.         {
  1374.         cursor_off();        /* so the user knows we're busy */
  1375.         out_flush();
  1376.         ++emsg_off;    /* So it doesn't beep if bad expr */
  1377.         i = do_search(NULL, firstc, ccline.cmdbuff, count,
  1378.                       SEARCH_KEEP + SEARCH_OPT + SEARCH_NOOF);
  1379.         --emsg_off;
  1380.         /* if interrupted while searching, behave like it failed */
  1381.         if (got_int)
  1382.         {
  1383.             (void)vpeekc();    /* remove <C-C> from input stream */
  1384.             got_int = FALSE;    /* don't abandon the command line */
  1385.             i = 0;
  1386.         }
  1387.         }
  1388.         if (i)
  1389.         highlight_match = TRUE;        /* highlight position */
  1390.         else
  1391.         highlight_match = FALSE;    /* remove highlight */
  1392.  
  1393.         /* first restore the old curwin values, so the screen is
  1394.          * positioned in the same way as the actual search command */
  1395.         curwin->w_leftcol = old_leftcol;
  1396.         curwin->w_topline = old_topline;
  1397. # ifdef FEAT_DIFF
  1398.         curwin->w_topfill = old_topfill;
  1399. # endif
  1400.         curwin->w_botline = old_botline;
  1401.         changed_cline_bef_curs();
  1402.         update_topline();
  1403.  
  1404.         if (i != 0)
  1405.         {
  1406.         /*
  1407.          * First move cursor to end of match, then to start.  This
  1408.          * moves the whole match onto the screen when 'nowrap' is set.
  1409.          */
  1410.         i = curwin->w_cursor.col;
  1411.         curwin->w_cursor.lnum += search_match_lines;
  1412.         curwin->w_cursor.col = search_match_endcol;
  1413.         validate_cursor();
  1414.         curwin->w_cursor.lnum -= search_match_lines;
  1415.         curwin->w_cursor.col = i;
  1416.         }
  1417.         validate_cursor();
  1418.  
  1419.         update_screen(NOT_VALID);
  1420.         msg_starthere();
  1421.         redrawcmdline();
  1422.         did_incsearch = TRUE;
  1423.     }
  1424. #else
  1425.     ;
  1426. #endif
  1427.     }
  1428.  
  1429. returncmd:
  1430.  
  1431. #ifdef FEAT_FKMAP
  1432.     cmd_fkmap = 0;
  1433. #endif
  1434.  
  1435. #ifdef FEAT_SEARCH_EXTRA
  1436.     if (did_incsearch)
  1437.     {
  1438.     curwin->w_cursor = old_cursor;
  1439.     curwin->w_curswant = old_curswant;
  1440.     curwin->w_leftcol = old_leftcol;
  1441.     curwin->w_topline = old_topline;
  1442. # ifdef FEAT_DIFF
  1443.     curwin->w_topfill = old_topfill;
  1444. # endif
  1445.     curwin->w_botline = old_botline;
  1446.     highlight_match = FALSE;
  1447.     validate_cursor();    /* needed for TAB */
  1448.     redraw_later(NOT_VALID);
  1449.     }
  1450. #endif
  1451.  
  1452.     if (ccline.cmdbuff != NULL)
  1453.     {
  1454.     /*
  1455.      * Put line in history buffer (":" and "=" only when it was typed).
  1456.      */
  1457. #ifdef FEAT_CMDHIST
  1458.     if (ccline.cmdlen && firstc != NUL
  1459.         && (some_key_typed || histype == HIST_SEARCH))
  1460.     {
  1461.         add_to_history(histype, ccline.cmdbuff, TRUE);
  1462.         if (firstc == ':')
  1463.         {
  1464.         vim_free(new_last_cmdline);
  1465.         new_last_cmdline = vim_strsave(ccline.cmdbuff);
  1466.         }
  1467.     }
  1468. #endif
  1469.  
  1470.     if (gotesc)        /* abandon command line */
  1471.     {
  1472.         vim_free(ccline.cmdbuff);
  1473.         ccline.cmdbuff = NULL;
  1474.         if (msg_scrolled == 0)
  1475.         compute_cmdrow();
  1476.         MSG("");
  1477.         redraw_cmdline = TRUE;
  1478.     }
  1479.     }
  1480.  
  1481.     /*
  1482.      * If the screen was shifted up, redraw the whole screen (later).
  1483.      * If the line is too long, clear it, so ruler and shown command do
  1484.      * not get printed in the middle of it.
  1485.      */
  1486.     msg_check();
  1487.     msg_scroll = save_msg_scroll;
  1488.     redir_off = FALSE;
  1489.  
  1490.     /* When the command line was typed, no need for a wait-return prompt. */
  1491.     if (some_key_typed)
  1492.     need_wait_return = FALSE;
  1493.  
  1494.     State = save_State;
  1495. #ifdef USE_IM_CONTROL
  1496.     if (b_im_ptr != NULL)
  1497.     im_save_status(b_im_ptr);
  1498.     im_set_active(FALSE);
  1499. #endif
  1500. #ifdef FEAT_MOUSE
  1501.     setmouse();
  1502. #endif
  1503.  
  1504.     return ccline.cmdbuff;
  1505. }
  1506.  
  1507. #if (defined(FEAT_CRYPT) || defined(FEAT_EVAL)) || defined(PROTO)
  1508. /*
  1509.  * Get a command line with a prompt.
  1510.  * This is prepared to be called recursively from getcmdline() (e.g. by
  1511.  * f_input() when evaluating an expression from CTRL-R =).
  1512.  * Returns the command line in allocated memory, or NULL.
  1513.  */
  1514.     char_u *
  1515. getcmdline_prompt(firstc, prompt, attr)
  1516.     int        firstc;
  1517.     char_u    *prompt;    /* command line prompt */
  1518.     int        attr;        /* attributes for prompt */
  1519. {
  1520.     char_u        *s;
  1521.     struct cmdline_info    save_ccline;
  1522.  
  1523.     save_ccline = ccline;
  1524.     ccline.cmdbuff = NULL;
  1525.     ccline.cmdprompt = prompt;
  1526.     ccline.cmdattr = attr;
  1527.     s = getcmdline(firstc, 1L, 0);
  1528.     ccline = save_ccline;
  1529.  
  1530.     return s;
  1531. }
  1532. #endif
  1533.  
  1534.     static int
  1535. cmdline_charsize(idx)
  1536.     int        idx;
  1537. {
  1538. #if defined(FEAT_CRYPT) || defined(FEAT_EVAL)
  1539.     if (cmdline_star)        /* showing '*', always 1 position */
  1540.     return 1;
  1541. #endif
  1542.     return ptr2cells(ccline.cmdbuff + idx);
  1543. }
  1544.  
  1545. /*
  1546.  * Compute the offset of the cursor on the command line for the prompt and
  1547.  * indent.
  1548.  */
  1549.     static void
  1550. set_cmdspos()
  1551. {
  1552.     if (ccline.cmdfirstc)
  1553.     ccline.cmdspos = 1 + ccline.cmdindent;
  1554.     else
  1555.     ccline.cmdspos = 0 + ccline.cmdindent;
  1556. }
  1557.  
  1558. /*
  1559.  * Compute the screen position for the cursor on the command line.
  1560.  */
  1561.     static void
  1562. set_cmdspos_cursor()
  1563. {
  1564.     int        i, m, c;
  1565.  
  1566.     set_cmdspos();
  1567.     if (KeyTyped)
  1568.     m = Columns * Rows;
  1569.     else
  1570.     m = MAXCOL;
  1571.     for (i = 0; i < ccline.cmdlen && i < ccline.cmdpos; ++i)
  1572.     {
  1573.     c = cmdline_charsize(i);
  1574. #ifdef FEAT_MBYTE
  1575.     /* Count ">" for double-wide char that doesn't fit. */
  1576.     if (has_mbyte
  1577.         && (*mb_ptr2cells)(ccline.cmdbuff + i) > 1
  1578.         && ccline.cmdspos % Columns + c > Columns)
  1579.         ccline.cmdspos++;
  1580. #endif
  1581.     /* If the cmdline doesn't fit, put cursor on last visible char. */
  1582.     if ((ccline.cmdspos += c) >= m)
  1583.     {
  1584.         ccline.cmdpos = i - 1;
  1585.         ccline.cmdspos -= c;
  1586.         break;
  1587.     }
  1588. #ifdef FEAT_MBYTE
  1589.     if (has_mbyte)
  1590.         i += (*mb_ptr2len_check)(ccline.cmdbuff + i) - 1;
  1591. #endif
  1592.     }
  1593. }
  1594.  
  1595. /*
  1596.  * Get an Ex command line for the ":" command.
  1597.  */
  1598. /* ARGSUSED */
  1599.     char_u *
  1600. getexline(c, dummy, indent)
  1601.     int        c;        /* normally ':', NUL for ":append" */
  1602.     void    *dummy;        /* cookie not used */
  1603.     int        indent;        /* indent for inside conditionals */
  1604. {
  1605.     /* When executing a register, remove ':' that's in front of each line. */
  1606.     if (exec_from_reg && vpeekc() == ':')
  1607.     (void)vgetc();
  1608.     return getcmdline(c, 1L, indent);
  1609. }
  1610.  
  1611. /*
  1612.  * Get an Ex command line for Ex mode.
  1613.  * In Ex mode we only use the OS supplied line editing features and no
  1614.  * mappings or abbreviations.
  1615.  */
  1616. /* ARGSUSED */
  1617.     char_u *
  1618. getexmodeline(c, dummy, indent)
  1619.     int        c;        /* normally ':', NUL for ":append" */
  1620.     void    *dummy;        /* cookie not used */
  1621.     int        indent;        /* indent for inside conditionals */
  1622. {
  1623.     garray_T        line_ga;
  1624.     int            len;
  1625.     int            off = 0;
  1626.     char_u        *p;
  1627.     int            finished = FALSE;
  1628. #if defined(FEAT_GUI) || defined(NO_COOKED_INPUT)
  1629.     int            startcol = 0;
  1630.     int            c1;
  1631.     int            escaped = FALSE;    /* CTRL-V typed */
  1632.     int            vcol = 0;
  1633. #endif
  1634.  
  1635.     /* Switch cursor on now.  This avoids that it happens after the "\n", which
  1636.      * confuses the system function that computes tabstops. */
  1637.     cursor_on();
  1638.  
  1639.     /* always start in column 0; write a newline if necessary */
  1640.     compute_cmdrow();
  1641.     if (msg_col)
  1642.     msg_putchar('\n');
  1643.     if (c == ':')
  1644.     {
  1645.     msg_putchar(':');
  1646.     while (indent-- > 0)
  1647.         msg_putchar(' ');
  1648. #if defined(FEAT_GUI) || defined(NO_COOKED_INPUT)
  1649.     startcol = msg_col;
  1650. #endif
  1651.     }
  1652.  
  1653.     ga_init2(&line_ga, 1, 30);
  1654.  
  1655.     /*
  1656.      * Get the line, one character at a time.
  1657.      */
  1658.     got_int = FALSE;
  1659.     while (!got_int && !finished)
  1660.     {
  1661.     if (ga_grow(&line_ga, 40) == FAIL)
  1662.         break;
  1663.     p = (char_u *)line_ga.ga_data + line_ga.ga_len;
  1664.  
  1665.     /* Get one character (inchar gets a third of maxlen characters!) */
  1666.     len = inchar(p + off, 3, -1L);
  1667.     if (len < 0)
  1668.         continue;        /* end of input script reached */
  1669.     /* for a special character, we need at least three characters */
  1670.     if ((*p == K_SPECIAL || *p == CSI) && off + len < 3)
  1671.     {
  1672.         off += len;
  1673.         continue;
  1674.     }
  1675.     len += off;
  1676.     off = 0;
  1677.  
  1678.     /*
  1679.      * When using the GUI, and for systems that don't have cooked input,
  1680.      * handle line editing here.
  1681.      */
  1682. #if defined(FEAT_GUI) || defined(NO_COOKED_INPUT)
  1683. # ifndef NO_COOKED_INPUT
  1684.     if (gui.in_use)
  1685. # endif
  1686.     {
  1687.         if (got_int)
  1688.         {
  1689.         msg_putchar('\n');
  1690.         break;
  1691.         }
  1692.  
  1693.         while (len > 0)
  1694.         {
  1695.         c1 = *p++;
  1696.         --len;
  1697.         if ((c1 == K_SPECIAL
  1698. #  if !defined(NO_COOKED_INPUT) || defined(FEAT_GUI)
  1699.                 || c1 == CSI
  1700. #  endif
  1701.             ) && len >= 2)
  1702.         {
  1703.             c1 = TO_SPECIAL(p[0], p[1]);
  1704.             p += 2;
  1705.             len -= 2;
  1706.         }
  1707.  
  1708.         if (!escaped)
  1709.         {
  1710.             /* CR typed means "enter", which is NL */
  1711.             if (c1 == '\r')
  1712.             c1 = '\n';
  1713.  
  1714.             if (c1 == BS || c1 == K_BS
  1715.                   || c1 == DEL || c1 == K_DEL || c1 == K_KDEL)
  1716.             {
  1717.             if (line_ga.ga_len > 0)
  1718.             {
  1719.                 int        i, v;
  1720.                 char_u    *q;
  1721.  
  1722.                 --line_ga.ga_len;
  1723.                 ++line_ga.ga_room;
  1724.                 /* compute column that cursor should be in */
  1725.                 v = 0;
  1726.                 q = ((char_u *)line_ga.ga_data);
  1727.                 for (i = 0; i < line_ga.ga_len; ++i)
  1728.                 {
  1729.                 if (*q == TAB)
  1730.                     v += 8 - v % 8;
  1731.                 else
  1732.                     v += ptr2cells(q);
  1733.                 ++q;
  1734.                 }
  1735.                 /* erase characters to position cursor */
  1736.                 while (vcol > v)
  1737.                 {
  1738.                 msg_putchar('\b');
  1739.                 msg_putchar(' ');
  1740.                 msg_putchar('\b');
  1741.                 --vcol;
  1742.                 }
  1743.             }
  1744.             continue;
  1745.             }
  1746.  
  1747.             if (c1 == Ctrl_U)
  1748.             {
  1749.             msg_col = startcol;
  1750.             msg_clr_eos();
  1751.             line_ga.ga_room += line_ga.ga_len;
  1752.             line_ga.ga_len = 0;
  1753.             continue;
  1754.             }
  1755.  
  1756.             if (c1 == Ctrl_V)
  1757.             {
  1758.             escaped = TRUE;
  1759.             continue;
  1760.             }
  1761.         }
  1762.  
  1763.         if (IS_SPECIAL(c1))
  1764.             c1 = '?';
  1765.         ((char_u *)line_ga.ga_data)[line_ga.ga_len] = c1;
  1766.         if (c1 == '\n')
  1767.             msg_putchar('\n');
  1768.         else if (c1 == TAB)
  1769.         {
  1770.             /* Don't use chartabsize(), 'ts' can be different */
  1771.             do
  1772.             {
  1773.             msg_putchar(' ');
  1774.             } while (++vcol % 8);
  1775.         }
  1776.         else
  1777.         {
  1778.             msg_outtrans_len(
  1779.                  ((char_u *)line_ga.ga_data) + line_ga.ga_len, 1);
  1780.             vcol += char2cells(c1);
  1781.         }
  1782.         ++line_ga.ga_len;
  1783.         --line_ga.ga_room;
  1784.         escaped = FALSE;
  1785.         }
  1786.         windgoto(msg_row, msg_col);
  1787.     }
  1788. # ifndef NO_COOKED_INPUT
  1789.     else
  1790. # endif
  1791. #endif
  1792. #ifndef NO_COOKED_INPUT
  1793.     {
  1794.         line_ga.ga_len += len;
  1795.         line_ga.ga_room -= len;
  1796.     }
  1797. #endif
  1798.     p = (char_u *)(line_ga.ga_data) + line_ga.ga_len;
  1799.     if (line_ga.ga_len && p[-1] == '\n')
  1800.     {
  1801.         finished = TRUE;
  1802.         --line_ga.ga_len;
  1803.         --p;
  1804.         *p = NUL;
  1805.     }
  1806.     }
  1807.  
  1808.     /* note that cursor has moved, because of the echoed <CR> */
  1809.     screen_down();
  1810.     /* make following messages go to the next line */
  1811.     msg_didout = FALSE;
  1812.     msg_col = 0;
  1813.     if (msg_row < Rows - 1)
  1814.     ++msg_row;
  1815.     emsg_on_display = FALSE;        /* don't want ui_delay() */
  1816.  
  1817.     if (got_int)
  1818.     ga_clear(&line_ga);
  1819.  
  1820.     return (char_u *)line_ga.ga_data;
  1821. }
  1822.  
  1823. #ifdef CURSOR_SHAPE
  1824. /*
  1825.  * Return TRUE if ccline.overstrike is on.
  1826.  */
  1827.     int
  1828. cmdline_overstrike()
  1829. {
  1830.     return ccline.overstrike;
  1831. }
  1832.  
  1833. /*
  1834.  * Return TRUE if the cursor is at the end of the cmdline.
  1835.  */
  1836.     int
  1837. cmdline_at_end()
  1838. {
  1839.     return (ccline.cmdpos >= ccline.cmdlen);
  1840. }
  1841. #endif
  1842.  
  1843. /*
  1844.  * Allocate a new command line buffer.
  1845.  * Assigns the new buffer to ccline.cmdbuff and ccline.cmdbufflen.
  1846.  * Returns the new value of ccline.cmdbuff and ccline.cmdbufflen.
  1847.  */
  1848.     static void
  1849. alloc_cmdbuff(len)
  1850.     int        len;
  1851. {
  1852.     /*
  1853.      * give some extra space to avoid having to allocate all the time
  1854.      */
  1855.     if (len < 80)
  1856.     len = 100;
  1857.     else
  1858.     len += 20;
  1859.  
  1860.     ccline.cmdbuff = alloc(len);    /* caller should check for out-of-memory */
  1861.     ccline.cmdbufflen = len;
  1862. }
  1863.  
  1864. /*
  1865.  * Re-allocate the command line to length len + something extra.
  1866.  * return FAIL for failure, OK otherwise
  1867.  */
  1868.     static int
  1869. realloc_cmdbuff(len)
  1870.     int        len;
  1871. {
  1872.     char_u    *p;
  1873.  
  1874.     p = ccline.cmdbuff;
  1875.     alloc_cmdbuff(len);            /* will get some more */
  1876.     if (ccline.cmdbuff == NULL)        /* out of memory */
  1877.     {
  1878.     ccline.cmdbuff = p;        /* keep the old one */
  1879.     return FAIL;
  1880.     }
  1881.     mch_memmove(ccline.cmdbuff, p, (size_t)ccline.cmdlen + 1);
  1882.     vim_free(p);
  1883.     return OK;
  1884. }
  1885.  
  1886. /*
  1887.  * Put a character on the command line.  Shifts the following text to the
  1888.  * right when "shift" is TRUE.  Used for CTRL-V, CTRL-K, etc.
  1889.  * "c" must be printable (fit in one display cell)!
  1890.  */
  1891.     void
  1892. putcmdline(c, shift)
  1893.     int        c;
  1894.     int        shift;
  1895. {
  1896.     if (cmd_silent)
  1897.     return;
  1898.     msg_no_more = TRUE;
  1899.     msg_putchar(c);
  1900.     if (shift)
  1901.     msg_outtrans_len(ccline.cmdbuff + ccline.cmdpos,
  1902.                            ccline.cmdlen - ccline.cmdpos);
  1903.     msg_no_more = FALSE;
  1904.     cursorcmd();
  1905. }
  1906.  
  1907. /*
  1908.  * Undo a putcmdline(c, FALSE).
  1909.  */
  1910.     void
  1911. unputcmdline()
  1912. {
  1913.     if (cmd_silent)
  1914.     return;
  1915.     msg_no_more = TRUE;
  1916.     if (ccline.cmdlen == ccline.cmdpos)
  1917.     msg_putchar(' ');
  1918.     else
  1919.     msg_outtrans_len(ccline.cmdbuff + ccline.cmdpos, 1);
  1920.     msg_no_more = FALSE;
  1921.     cursorcmd();
  1922. }
  1923.  
  1924. /*
  1925.  * Put the given string, of the given length, onto the command line.
  1926.  * If len is -1, then STRLEN() is used to calculate the length.
  1927.  * If 'redraw' is TRUE then the new part of the command line, and the remaining
  1928.  * part will be redrawn, otherwise it will not.  If this function is called
  1929.  * twice in a row, then 'redraw' should be FALSE and redrawcmd() should be
  1930.  * called afterwards.
  1931.  */
  1932.     int
  1933. put_on_cmdline(str, len, redraw)
  1934.     char_u    *str;
  1935.     int        len;
  1936.     int        redraw;
  1937. {
  1938.     int        retval;
  1939.     int        i;
  1940.     int        m;
  1941.     int        c;
  1942.  
  1943.     if (len < 0)
  1944.     len = (int)STRLEN(str);
  1945.  
  1946.     /* Check if ccline.cmdbuff needs to be longer */
  1947.     if (ccline.cmdlen + len + 1 >= ccline.cmdbufflen)
  1948.     retval = realloc_cmdbuff(ccline.cmdlen + len);
  1949.     else
  1950.     retval = OK;
  1951.     if (retval == OK)
  1952.     {
  1953.     if (!ccline.overstrike)
  1954.     {
  1955.         mch_memmove(ccline.cmdbuff + ccline.cmdpos + len,
  1956.                            ccline.cmdbuff + ccline.cmdpos,
  1957.                      (size_t)(ccline.cmdlen - ccline.cmdpos));
  1958.         ccline.cmdlen += len;
  1959.     }
  1960.     else
  1961.     {
  1962. #ifdef FEAT_MBYTE
  1963.         if (has_mbyte)
  1964.         {
  1965.         /* Count nr of characters in the new string. */
  1966.         m = 0;
  1967.         for (i = 0; i < len; i += (*mb_ptr2len_check)(str + i))
  1968.             ++m;
  1969.         /* Count nr of bytes in cmdline that are overwritten by these
  1970.          * characters. */
  1971.         for (i = ccline.cmdpos; i < ccline.cmdlen && m > 0;
  1972.                  i += (*mb_ptr2len_check)(ccline.cmdbuff + i))
  1973.             --m;
  1974.         if (i < ccline.cmdlen)
  1975.         {
  1976.             mch_memmove(ccline.cmdbuff + ccline.cmdpos + len,
  1977.                 ccline.cmdbuff + i, (size_t)(ccline.cmdlen - i));
  1978.             ccline.cmdlen += ccline.cmdpos + len - i;
  1979.         }
  1980.         else
  1981.             ccline.cmdlen = ccline.cmdpos + len;
  1982.         }
  1983.         else
  1984. #endif
  1985.         if (ccline.cmdpos + len > ccline.cmdlen)
  1986.         ccline.cmdlen = ccline.cmdpos + len;
  1987.     }
  1988.     mch_memmove(ccline.cmdbuff + ccline.cmdpos, str, (size_t)len);
  1989.     ccline.cmdbuff[ccline.cmdlen] = NUL;
  1990.  
  1991. #ifdef FEAT_MBYTE
  1992.     /* When the inserted text starts with a composing character, backup to
  1993.      * the character before it.  There could be two of them. */
  1994.     c = 0;
  1995.     while (enc_utf8 && ccline.cmdpos > 0
  1996.          && utf_iscomposing(utf_ptr2char(ccline.cmdbuff + ccline.cmdpos)))
  1997.     {
  1998.         c = (*mb_head_off)(ccline.cmdbuff,
  1999.                       ccline.cmdbuff + ccline.cmdpos - 1) + 1;
  2000.         ccline.cmdpos -= c;
  2001.         len += c;
  2002.     }
  2003.     if (c != 0)
  2004.     {
  2005.         /* Also backup the cursor position. */
  2006.         c -= ptr2cells(ccline.cmdbuff + ccline.cmdpos);
  2007.         ccline.cmdspos -= c;
  2008.         msg_col -= c;
  2009.         if (msg_col < 0)
  2010.         {
  2011.         msg_col += Columns;
  2012.         --msg_row;
  2013.         }
  2014.     }
  2015. #endif
  2016.  
  2017.     if (redraw && !cmd_silent)
  2018.     {
  2019. #if defined(FEAT_CRYPT) || defined(FEAT_EVAL)
  2020.         if (cmdline_star)        /* only write '*' characters */
  2021.         for (i = ccline.cmdpos; i < ccline.cmdlen; ++i)
  2022.             msg_putchar('*');
  2023.         else
  2024. #endif
  2025.         {
  2026.         msg_no_more = TRUE;
  2027.         i = cmdline_row;
  2028.         msg_outtrans_len(ccline.cmdbuff + ccline.cmdpos,
  2029.                            ccline.cmdlen - ccline.cmdpos);
  2030.         /* Avoid clearing the rest of the line too often. */
  2031.         if (cmdline_row != i || ccline.overstrike)
  2032.             msg_clr_eos();
  2033.         msg_no_more = FALSE;
  2034.         }
  2035.     }
  2036. #ifdef FEAT_FKMAP
  2037.     /*
  2038.      * If we are in Farsi command mode, the character input must be in
  2039.      * Insert mode. So do not advance the cmdpos.
  2040.      */
  2041.     if (!cmd_fkmap)
  2042. #endif
  2043.     {
  2044.         if (KeyTyped)
  2045.         m = Columns * Rows;
  2046.         else
  2047.         m = MAXCOL;
  2048.         for (i = 0; i < len; ++i)
  2049.         {
  2050.         c = cmdline_charsize(ccline.cmdpos);
  2051. #ifdef FEAT_MBYTE
  2052.         /* count ">" for a double-wide char that doesn't fit. */
  2053.         if (has_mbyte
  2054.             && (*mb_ptr2cells)(ccline.cmdbuff + ccline.cmdpos) > 1
  2055.             && ccline.cmdspos % Columns + c > Columns)
  2056.             ccline.cmdspos++;
  2057. #endif
  2058.         /* Stop cursor at the end of the screen */
  2059.         if (ccline.cmdspos + c >= m)
  2060.             break;
  2061.         ccline.cmdspos += c;
  2062. #ifdef FEAT_MBYTE
  2063.         if (has_mbyte)
  2064.         {
  2065.             c = (*mb_ptr2len_check)(ccline.cmdbuff + ccline.cmdpos) - 1;
  2066.             if (c > len - i - 1)
  2067.             c = len - i - 1;
  2068.             ccline.cmdpos += c;
  2069.             i += c;
  2070.         }
  2071. #endif
  2072.         ++ccline.cmdpos;
  2073.         }
  2074.     }
  2075.     }
  2076.     if (redraw)
  2077.     msg_check();
  2078.     return retval;
  2079. }
  2080.  
  2081. #ifdef FEAT_WILDMENU
  2082. /*
  2083.  * Delete characters on the command line, from "from" to the current
  2084.  * position.
  2085.  */
  2086.     static void
  2087. cmdline_del(from)
  2088.     int from;
  2089. {
  2090.     mch_memmove(ccline.cmdbuff + from, ccline.cmdbuff + ccline.cmdpos,
  2091.         (size_t)(ccline.cmdlen - ccline.cmdpos + 1));
  2092.     ccline.cmdlen -= ccline.cmdpos - from;
  2093.     ccline.cmdpos = from;
  2094. }
  2095. #endif
  2096.  
  2097. /*
  2098.  * this fuction is called when the screen size changes and with incremental
  2099.  * search
  2100.  */
  2101.     void
  2102. redrawcmdline()
  2103. {
  2104.     if (cmd_silent)
  2105.     return;
  2106.     need_wait_return = FALSE;
  2107.     compute_cmdrow();
  2108.     redrawcmd();
  2109.     cursorcmd();
  2110. }
  2111.  
  2112.     static void
  2113. redrawcmdprompt()
  2114. {
  2115.     int        i;
  2116.  
  2117.     if (cmd_silent)
  2118.     return;
  2119.     if (ccline.cmdfirstc)
  2120.     msg_putchar(ccline.cmdfirstc);
  2121.     if (ccline.cmdprompt != NULL)
  2122.     {
  2123.     msg_puts_attr(ccline.cmdprompt, ccline.cmdattr);
  2124.     ccline.cmdindent = msg_col;
  2125.     }
  2126.     else
  2127.     for (i = ccline.cmdindent; i > 0; --i)
  2128.         msg_putchar(' ');
  2129. }
  2130.  
  2131. /*
  2132.  * Redraw what is currently on the command line.
  2133.  */
  2134.     void
  2135. redrawcmd()
  2136. {
  2137. #if defined(FEAT_CRYPT) || defined(FEAT_EVAL)
  2138.     int        i;
  2139. #endif
  2140.  
  2141.     if (cmd_silent)
  2142.     return;
  2143.  
  2144.     msg_start();
  2145.     redrawcmdprompt();
  2146. #if defined(FEAT_CRYPT) || defined(FEAT_EVAL)
  2147.     if (cmdline_star)
  2148.     {
  2149.     /* Show '*' for every character typed */
  2150.     for (i = 0; i < ccline.cmdlen; ++i)
  2151.         msg_putchar('*');
  2152.     msg_clr_eos();
  2153.     }
  2154.     else
  2155. #endif
  2156.     {
  2157.     /* Don't use more prompt, truncate the cmdline if it doesn't fit. */
  2158.     msg_no_more = TRUE;
  2159.     msg_outtrans_len(ccline.cmdbuff, ccline.cmdlen);
  2160.     msg_clr_eos();
  2161.     msg_no_more = FALSE;
  2162.     }
  2163.     set_cmdspos_cursor();
  2164.  
  2165.     /*
  2166.      * An emsg() before may have set msg_scroll. This is used in normal mode,
  2167.      * in cmdline mode we can reset them now.
  2168.      */
  2169.     msg_scroll = FALSE;        /* next message overwrites cmdline */
  2170.  
  2171.     /* Typing ':' at the more prompt may set skip_redraw.  We don't want this
  2172.      * in cmdline mode */
  2173.     skip_redraw = FALSE;
  2174. }
  2175.  
  2176.     void
  2177. compute_cmdrow()
  2178. {
  2179.     if (exmode_active || msg_scrolled)
  2180.     cmdline_row = Rows - 1;
  2181.     else
  2182.     cmdline_row = W_WINROW(lastwin) + lastwin->w_height
  2183.                            + W_STATUS_HEIGHT(lastwin);
  2184. }
  2185.  
  2186.     static void
  2187. cursorcmd()
  2188. {
  2189.     if (cmd_silent)
  2190.     return;
  2191.     msg_row = cmdline_row + (ccline.cmdspos / (int)Columns);
  2192.     msg_col = ccline.cmdspos % (int)Columns;
  2193.     if (msg_row >= Rows)
  2194.     msg_row = Rows - 1;
  2195.     windgoto(msg_row, msg_col);
  2196. #ifdef MCH_CURSOR_SHAPE
  2197.     mch_update_cursor();
  2198. #endif
  2199. }
  2200.  
  2201.     void
  2202. gotocmdline(clr)
  2203.     int            clr;
  2204. {
  2205.     msg_start();
  2206.     msg_col = 0;        /* always start in column 0 */
  2207.     if (clr)            /* clear the bottom line(s) */
  2208.     msg_clr_eos();        /* will reset clear_cmdline */
  2209.     windgoto(cmdline_row, 0);
  2210. }
  2211.  
  2212. /*
  2213.  * Check the word in front of the cursor for an abbreviation.
  2214.  * Called when the non-id character "c" has been entered.
  2215.  * When an abbreviation is recognized it is removed from the text with
  2216.  * backspaces and the replacement string is inserted, followed by "c".
  2217.  */
  2218.     static int
  2219. ccheck_abbr(c)
  2220.     int c;
  2221. {
  2222.     if (p_paste || no_abbr)        /* no abbreviations or in paste mode */
  2223.     return FALSE;
  2224.  
  2225.     return check_abbr(c, ccline.cmdbuff, ccline.cmdpos, 0);
  2226. }
  2227.  
  2228. /*
  2229.  * Return FAIL if this is not an appropriate context in which to do
  2230.  * completion of anything, return OK if it is (even if there are no matches).
  2231.  * For the caller, this means that the character is just passed through like a
  2232.  * normal character (instead of being expanded).  This allows :s/^I^D etc.
  2233.  */
  2234.     static int
  2235. nextwild(xp, type, options)
  2236.     expand_T    *xp;
  2237.     int        type;
  2238.     int        options;    /* extra options for ExpandOne() */
  2239. {
  2240.     int        i, j;
  2241.     char_u    *p1;
  2242.     char_u    *p2;
  2243.     int        oldlen;
  2244.     int        difflen;
  2245.     int        v;
  2246.  
  2247.     if (cmd_numfiles == -1)
  2248.     set_expand_context(xp);
  2249.  
  2250.     if (xp->xp_context == EXPAND_UNSUCCESSFUL)
  2251.     {
  2252.     beep_flush();
  2253.     return OK;  /* Something illegal on command line */
  2254.     }
  2255.     if (xp->xp_context == EXPAND_NOTHING)
  2256.     {
  2257.     /* Caller can use the character as a normal char instead */
  2258.     return FAIL;
  2259.     }
  2260.  
  2261.     MSG_PUTS("...");        /* show that we are busy */
  2262.     out_flush();
  2263.  
  2264.     i = (int)(xp->xp_pattern - ccline.cmdbuff);
  2265.     oldlen = ccline.cmdpos - i;
  2266.  
  2267.     if (type == WILD_NEXT || type == WILD_PREV)
  2268.     {
  2269.     /*
  2270.      * Get next/previous match for a previous expanded pattern.
  2271.      */
  2272.     p2 = ExpandOne(xp, NULL, NULL, 0, type);
  2273.     }
  2274.     else
  2275.     {
  2276.     /*
  2277.      * Translate string into pattern and expand it.
  2278.      */
  2279.     if ((p1 = addstar(&ccline.cmdbuff[i], oldlen, xp->xp_context)) == NULL)
  2280.         p2 = NULL;
  2281.     else
  2282.     {
  2283.         p2 = ExpandOne(xp, p1, vim_strnsave(&ccline.cmdbuff[i], oldlen),
  2284.             WILD_HOME_REPLACE|WILD_ADD_SLASH|WILD_SILENT|WILD_ESCAPE
  2285.                                   |options, type);
  2286.         vim_free(p1);
  2287.         /* longest match: make sure it is not shorter (happens with :help */
  2288.         if (p2 != NULL && type == WILD_LONGEST)
  2289.         {
  2290.         for (j = 0; j < oldlen; ++j)
  2291.              if (ccline.cmdbuff[i + j] == '*'
  2292.                  || ccline.cmdbuff[i + j] == '?')
  2293.              break;
  2294.         if ((int)STRLEN(p2) < j)
  2295.         {
  2296.             vim_free(p2);
  2297.             p2 = NULL;
  2298.         }
  2299.         }
  2300.     }
  2301.     }
  2302.  
  2303.     if (p2 != NULL && !got_int)
  2304.     {
  2305.     difflen = (int)STRLEN(p2) - oldlen;
  2306.     if (ccline.cmdlen + difflen > ccline.cmdbufflen - 4)
  2307.     {
  2308.         v = realloc_cmdbuff(ccline.cmdlen + difflen);
  2309.         xp->xp_pattern = ccline.cmdbuff + i;
  2310.     }
  2311.     else
  2312.         v = OK;
  2313.     if (v == OK)
  2314.     {
  2315.         vim_strncpy(&ccline.cmdbuff[ccline.cmdpos + difflen],
  2316.                            &ccline.cmdbuff[ccline.cmdpos],
  2317.             ccline.cmdlen - ccline.cmdpos + 1);
  2318.         STRNCPY(&ccline.cmdbuff[i], p2, STRLEN(p2));
  2319.         ccline.cmdlen += difflen;
  2320.         ccline.cmdpos += difflen;
  2321.     }
  2322.     }
  2323.     vim_free(p2);
  2324.  
  2325.     redrawcmd();
  2326.  
  2327.     /* When expanding a ":map" command and no matches are found, assume that
  2328.      * the key is supposed to be inserted literally */
  2329.     if (xp->xp_context == EXPAND_MAPPINGS && p2 == NULL)
  2330.     return FAIL;
  2331.  
  2332.     if (cmd_numfiles <= 0 && p2 == NULL)
  2333.     beep_flush();
  2334.     else if (cmd_numfiles == 1)
  2335.     /* free expanded pattern */
  2336.     (void)ExpandOne(xp, NULL, NULL, 0, WILD_FREE);
  2337.  
  2338.     return OK;
  2339. }
  2340.  
  2341. /*
  2342.  * Do wildcard expansion on the string 'str'.
  2343.  * Chars that should not be expanded must be preceded with a backslash.
  2344.  * Return a pointer to alloced memory containing the new string.
  2345.  * Return NULL for failure.
  2346.  *
  2347.  * Results are cached in cmd_files and cmd_numfiles.
  2348.  *
  2349.  * mode = WILD_FREE:        just free previously expanded matches
  2350.  * mode = WILD_EXPAND_FREE: normal expansion, do not keep matches
  2351.  * mode = WILD_EXPAND_KEEP: normal expansion, keep matches
  2352.  * mode = WILD_NEXT:        use next match in multiple match, wrap to first
  2353.  * mode = WILD_PREV:        use previous match in multiple match, wrap to first
  2354.  * mode = WILD_ALL:        return all matches concatenated
  2355.  * mode = WILD_LONGEST:        return longest matched part
  2356.  *
  2357.  * options = WILD_LIST_NOTFOUND:    list entries without a match
  2358.  * options = WILD_HOME_REPLACE:        do home_replace() for buffer names
  2359.  * options = WILD_USE_NL:        Use '\n' for WILD_ALL
  2360.  * options = WILD_NO_BEEP:        Don't beep for multiple matches
  2361.  * options = WILD_ADD_SLASH:        add a slash after directory names
  2362.  * options = WILD_KEEP_ALL:        don't remove 'wildignore' entries
  2363.  * options = WILD_SILENT:        don't print warning messages
  2364.  * options = WILD_ESCAPE:        put backslash before special chars
  2365.  *
  2366.  * The variable xp->xp_context must have been set!
  2367.  */
  2368.     char_u *
  2369. ExpandOne(xp, str, orig, options, mode)
  2370.     expand_T    *xp;
  2371.     char_u    *str;
  2372.     char_u    *orig;        /* allocated copy of original of expanded string */
  2373.     int        options;
  2374.     int        mode;
  2375. {
  2376.     char_u    *ss = NULL;
  2377.     static int    findex;
  2378.     static char_u *orig_save = NULL;    /* kept value of orig */
  2379.     int        i;
  2380.     long_u    len;
  2381.     int        non_suf_match;        /* number without matching suffix */
  2382.  
  2383.     /*
  2384.      * first handle the case of using an old match
  2385.      */
  2386.     if (mode == WILD_NEXT || mode == WILD_PREV)
  2387.     {
  2388.     if (cmd_numfiles > 0)
  2389.     {
  2390.         if (mode == WILD_PREV)
  2391.         {
  2392.         if (findex == -1)
  2393.             findex = cmd_numfiles;
  2394.         --findex;
  2395.         }
  2396.         else    /* mode == WILD_NEXT */
  2397.         ++findex;
  2398.  
  2399.         /*
  2400.          * When wrapping around, return the original string, set findex to
  2401.          * -1.
  2402.          */
  2403.         if (findex < 0)
  2404.         {
  2405.         if (orig_save == NULL)
  2406.             findex = cmd_numfiles - 1;
  2407.         else
  2408.             findex = -1;
  2409.         }
  2410.         if (findex >= cmd_numfiles)
  2411.         {
  2412.         if (orig_save == NULL)
  2413.             findex = 0;
  2414.         else
  2415.             findex = -1;
  2416.         }
  2417. #ifdef FEAT_WILDMENU
  2418.         if (p_wmnu)
  2419.         win_redr_status_matches(xp, cmd_numfiles, cmd_files, findex);
  2420. #endif
  2421.         if (findex == -1)
  2422.         return vim_strsave(orig_save);
  2423.         return vim_strsave(cmd_files[findex]);
  2424.     }
  2425.     else
  2426.         return NULL;
  2427.     }
  2428.  
  2429. /* free old names */
  2430.     if (cmd_numfiles != -1 && mode != WILD_ALL && mode != WILD_LONGEST)
  2431.     {
  2432.     FreeWild(cmd_numfiles, cmd_files);
  2433.     cmd_numfiles = -1;
  2434.     vim_free(orig_save);
  2435.     orig_save = NULL;
  2436.     }
  2437.     findex = 0;
  2438.  
  2439.     if (mode == WILD_FREE)    /* only release file name */
  2440.     return NULL;
  2441.  
  2442.     if (cmd_numfiles == -1)
  2443.     {
  2444.     vim_free(orig_save);
  2445.     orig_save = orig;
  2446.  
  2447.     /*
  2448.      * Do the expansion.
  2449.      */
  2450.     if (ExpandFromContext(xp, str, &cmd_numfiles, &cmd_files,
  2451.                                  options) == FAIL)
  2452.     {
  2453. #ifdef FNAME_ILLEGAL
  2454.         /* Illegal file name has been silently skipped.  But when there
  2455.          * are wildcards, the real problem is that there was no match,
  2456.          * causing the pattern to be added, which has illegal characters.
  2457.          */
  2458.         if (!(options & WILD_SILENT) && (options & WILD_LIST_NOTFOUND))
  2459.         EMSG2(_(e_nomatch2), str);
  2460. #endif
  2461.     }
  2462.     else if (cmd_numfiles == 0)
  2463.     {
  2464.         if (!(options & WILD_SILENT))
  2465.         EMSG2(_(e_nomatch2), str);
  2466.     }
  2467.     else
  2468.     {
  2469.         /* Escape the matches for use on the command line. */
  2470.         ExpandEscape(xp, str, cmd_numfiles, cmd_files, options);
  2471.  
  2472.         /*
  2473.          * Check for matching suffixes in file names.
  2474.          */
  2475.         if (mode != WILD_ALL && mode != WILD_LONGEST)
  2476.         {
  2477.         if (cmd_numfiles)
  2478.             non_suf_match = cmd_numfiles;
  2479.         else
  2480.             non_suf_match = 1;
  2481.         if ((xp->xp_context == EXPAND_FILES
  2482.                 || xp->xp_context == EXPAND_DIRECTORIES)
  2483.             && cmd_numfiles > 1)
  2484.         {
  2485.             /*
  2486.              * More than one match; check suffix.
  2487.              * The files will have been sorted on matching suffix in
  2488.              * expand_wildcards, only need to check the first two.
  2489.              */
  2490.             non_suf_match = 0;
  2491.             for (i = 0; i < 2; ++i)
  2492.             if (match_suffix(cmd_files[i]))
  2493.                 ++non_suf_match;
  2494.         }
  2495.         if (non_suf_match != 1)
  2496.         {
  2497.             /* Can we ever get here unless it's while expanding
  2498.              * interactively?  If not, we can get rid of this all
  2499.              * together. Don't really want to wait for this message
  2500.              * (and possibly have to hit return to continue!).
  2501.              */
  2502.             if (!(options & WILD_SILENT))
  2503.             EMSG(_(e_toomany));
  2504.             else if (!(options & WILD_NO_BEEP))
  2505.             beep_flush();
  2506.         }
  2507.         if (!(non_suf_match != 1 && mode == WILD_EXPAND_FREE))
  2508.             ss = vim_strsave(cmd_files[0]);
  2509.         }
  2510.     }
  2511.     }
  2512.  
  2513.     /* Find longest common part */
  2514.     if (mode == WILD_LONGEST && cmd_numfiles > 0)
  2515.     {
  2516.     for (len = 0; cmd_files[0][len]; ++len)
  2517.     {
  2518.         for (i = 0; i < cmd_numfiles; ++i)
  2519.         {
  2520. #ifdef CASE_INSENSITIVE_FILENAME
  2521.         if (xp->xp_context == EXPAND_DIRECTORIES
  2522.             || xp->xp_context == EXPAND_FILES
  2523.             || xp->xp_context == EXPAND_BUFFERS)
  2524.         {
  2525.             if (TO_LOWER(cmd_files[i][len]) !=
  2526.                            TO_LOWER(cmd_files[0][len]))
  2527.             break;
  2528.         }
  2529.         else
  2530. #endif
  2531.              if (cmd_files[i][len] != cmd_files[0][len])
  2532.             break;
  2533.         }
  2534.         if (i < cmd_numfiles)
  2535.         {
  2536.         if (!(options & WILD_NO_BEEP))
  2537.             vim_beep();
  2538.         break;
  2539.         }
  2540.     }
  2541.     ss = alloc((unsigned)len + 1);
  2542.     if (ss)
  2543.     {
  2544.         STRNCPY(ss, cmd_files[0], len);
  2545.         ss[len] = NUL;
  2546.     }
  2547.     findex = -1;                /* next p_wc gets first one */
  2548.     }
  2549.  
  2550.     /* Concatenate all matching names */
  2551.     if (mode == WILD_ALL && cmd_numfiles > 0)
  2552.     {
  2553.     len = 0;
  2554.     for (i = 0; i < cmd_numfiles; ++i)
  2555.         len += (long_u)STRLEN(cmd_files[i]) + 1;
  2556.     ss = lalloc(len, TRUE);
  2557.     if (ss != NULL)
  2558.     {
  2559.         *ss = NUL;
  2560.         for (i = 0; i < cmd_numfiles; ++i)
  2561.         {
  2562.         STRCAT(ss, cmd_files[i]);
  2563.         if (i != cmd_numfiles - 1)
  2564.             STRCAT(ss, (options & WILD_USE_NL) ? "\n" : " ");
  2565.         }
  2566.     }
  2567.     }
  2568.  
  2569.     if (mode == WILD_EXPAND_FREE || mode == WILD_ALL)
  2570.     {
  2571.     FreeWild(cmd_numfiles, cmd_files);
  2572.     cmd_numfiles = -1;
  2573.     }
  2574.  
  2575.     return ss;
  2576. }
  2577.  
  2578.     void
  2579. ExpandEscape(xp, str, numfiles, files, options)
  2580.     expand_T    *xp;
  2581.     char_u    *str;
  2582.     int        numfiles;
  2583.     char_u    **files;
  2584.     int        options;
  2585. {
  2586.     int        i;
  2587.     char_u    *p;
  2588.  
  2589.     /*
  2590.      * May change home directory back to "~"
  2591.      */
  2592.     if (options & WILD_HOME_REPLACE)
  2593.     tilde_replace(str, numfiles, files);
  2594.  
  2595.     if (options & WILD_ESCAPE)
  2596.     {
  2597.     if (xp->xp_context == EXPAND_FILES
  2598.         || xp->xp_context == EXPAND_BUFFERS
  2599.         || xp->xp_context == EXPAND_DIRECTORIES)
  2600.     {
  2601.         /*
  2602.          * Insert a backslash into a file name before a space, \, %, #
  2603.          * and wildmatch characters, except '~'.
  2604.          */
  2605.         for (i = 0; i < numfiles; ++i)
  2606.         {
  2607.         /* for ":set path=" we need to escape spaces twice */
  2608.         if (xp->xp_set_path)
  2609.         {
  2610.             p = vim_strsave_escaped(files[i], (char_u *)" ");
  2611.             if (p != NULL)
  2612.             {
  2613.             vim_free(files[i]);
  2614.             files[i] = p;
  2615. #if defined(BACKSLASH_IN_FILENAME) || defined(COLON_AS_PATHSEP)
  2616.             p = vim_strsave_escaped(files[i], (char_u *)" ");
  2617.             if (p != NULL)
  2618.             {
  2619.                 vim_free(files[i]);
  2620.                 files[i] = p;
  2621.             }
  2622. #endif
  2623.             }
  2624.         }
  2625.         p = vim_strsave_escaped(files[i], PATH_ESC_CHARS);
  2626.         if (p != NULL)
  2627.         {
  2628.             vim_free(files[i]);
  2629.             files[i] = p;
  2630.         }
  2631.  
  2632.         /* If 'str' starts with "\~", replace "~" at start of
  2633.          * files[i] with "\~". */
  2634.         if (str[0] == '\\' && str[1] == '~' && files[i][0] == '~')
  2635.         {
  2636.             p = alloc((unsigned)(STRLEN(files[i]) + 2));
  2637.             if (p != NULL)
  2638.             {
  2639.             p[0] = '\\';
  2640.             STRCPY(p + 1, files[i]);
  2641.             vim_free(files[i]);
  2642.             files[i] = p;
  2643.             }
  2644.         }
  2645.         }
  2646.         xp->xp_set_path = FALSE;
  2647.     }
  2648.     else if (xp->xp_context == EXPAND_TAGS)
  2649.     {
  2650.         /*
  2651.          * Insert a backslash before characters in a tag name that
  2652.          * would terminate the ":tag" command.
  2653.          */
  2654.         for (i = 0; i < numfiles; ++i)
  2655.         {
  2656.         p = vim_strsave_escaped(files[i], (char_u *)"\\|\"");
  2657.         if (p != NULL)
  2658.         {
  2659.             vim_free(files[i]);
  2660.             files[i] = p;
  2661.         }
  2662.         }
  2663.     }
  2664.     }
  2665. }
  2666.  
  2667. /*
  2668.  * For each file name in files[num_files]:
  2669.  * If 'orig_pat' starts with "~/", replace the home directory with "~".
  2670.  */
  2671.     void
  2672. tilde_replace(orig_pat, num_files, files)
  2673.     char_u  *orig_pat;
  2674.     int        num_files;
  2675.     char_u  **files;
  2676. {
  2677.     int        i;
  2678.     char_u  *p;
  2679.  
  2680.     if (orig_pat[0] == '~' && vim_ispathsep(orig_pat[1]))
  2681.     {
  2682.     for (i = 0; i < num_files; ++i)
  2683.     {
  2684.         p = home_replace_save(NULL, files[i]);
  2685.         if (p != NULL)
  2686.         {
  2687.         vim_free(files[i]);
  2688.         files[i] = p;
  2689.         }
  2690.     }
  2691.     }
  2692. }
  2693.  
  2694. /*
  2695.  * Show all matches for completion on the command line.
  2696.  * Returns EXPAND_NOTHING when the character that triggered expansion should
  2697.  * be inserted like a normal character.
  2698.  */
  2699. /*ARGSUSED*/
  2700.     static int
  2701. showmatches(xp, wildmenu)
  2702.     expand_T    *xp;
  2703.     int        wildmenu;
  2704. {
  2705.     int        num_files;
  2706.     char_u    **files_found;
  2707.     int        i, j, k;
  2708.     int        maxlen;
  2709.     int        lines;
  2710.     int        columns;
  2711.     char_u    *p;
  2712.     int        lastlen;
  2713.     int        attr;
  2714.  
  2715.     if (cmd_numfiles == -1)
  2716.     {
  2717.     set_expand_context(xp);
  2718.     i = expand_cmdline(xp, ccline.cmdbuff, ccline.cmdpos,
  2719.                             &num_files, &files_found);
  2720.     if (i != EXPAND_OK)
  2721.         return i;
  2722.  
  2723.     }
  2724.     else
  2725.     {
  2726.     num_files = cmd_numfiles;
  2727.     files_found = cmd_files;
  2728.     }
  2729.  
  2730. #ifdef FEAT_WILDMENU
  2731.     if (!wildmenu)
  2732.     {
  2733. #endif
  2734.     msg_didany = FALSE;        /* lines_left will be set */
  2735.     msg_start();            /* prepare for paging */
  2736.     msg_putchar('\n');
  2737.     out_flush();
  2738.     cmdline_row = msg_row;
  2739.     msg_didany = FALSE;        /* lines_left will be set again */
  2740.     msg_start();            /* prepare for paging */
  2741. #ifdef FEAT_WILDMENU
  2742.     }
  2743. #endif
  2744.  
  2745.     if (got_int)
  2746.     got_int = FALSE;    /* only int. the completion, not the cmd line */
  2747. #ifdef FEAT_WILDMENU
  2748.     else if (wildmenu)
  2749.     win_redr_status_matches(xp, num_files, files_found, 0);
  2750. #endif
  2751.     else
  2752.     {
  2753.     /* find the length of the longest file name */
  2754.     maxlen = 0;
  2755.     for (i = 0; i < num_files; ++i)
  2756.     {
  2757.         if (xp->xp_context == EXPAND_FILES
  2758.                       || xp->xp_context == EXPAND_BUFFERS)
  2759.         {
  2760.         home_replace(NULL, files_found[i], NameBuff, MAXPATHL, TRUE);
  2761.         j = vim_strsize(NameBuff);
  2762.         }
  2763.         else
  2764.         j = vim_strsize(files_found[i]);
  2765.         if (j > maxlen)
  2766.         maxlen = j;
  2767.     }
  2768.  
  2769.     if (xp->xp_context == EXPAND_TAGS_LISTFILES)
  2770.         lines = num_files;
  2771.     else
  2772.     {
  2773.         /* compute the number of columns and lines for the listing */
  2774.         maxlen += 2;    /* two spaces between file names */
  2775.         columns = ((int)Columns + 2) / maxlen;
  2776.         if (columns < 1)
  2777.         columns = 1;
  2778.         lines = (num_files + columns - 1) / columns;
  2779.     }
  2780.  
  2781.     attr = hl_attr(HLF_D);    /* find out highlighting for directories */
  2782.  
  2783.     if (xp->xp_context == EXPAND_TAGS_LISTFILES)
  2784.     {
  2785.         MSG_PUTS_ATTR(_("tagname"), hl_attr(HLF_T));
  2786.         msg_clr_eos();
  2787.         msg_advance(maxlen - 3);
  2788.         MSG_PUTS_ATTR(_(" kind file\n"), hl_attr(HLF_T));
  2789.     }
  2790.  
  2791.     /* list the files line by line */
  2792.     for (i = 0; i < lines; ++i)
  2793.     {
  2794.         lastlen = 999;
  2795.         for (k = i; k < num_files; k += lines)
  2796.         {
  2797.         if (xp->xp_context == EXPAND_TAGS_LISTFILES)
  2798.         {
  2799.             msg_outtrans_attr(files_found[k], hl_attr(HLF_D));
  2800.             p = files_found[k] + STRLEN(files_found[k]) + 1;
  2801.             msg_advance(maxlen + 1);
  2802.             msg_puts(p);
  2803.             msg_advance(maxlen + 3);
  2804.             msg_puts_long_attr(p + 2, hl_attr(HLF_D));
  2805.             break;
  2806.         }
  2807.         for (j = maxlen - lastlen; --j >= 0; )
  2808.             msg_putchar(' ');
  2809.         if (xp->xp_context == EXPAND_FILES
  2810.                       || xp->xp_context == EXPAND_BUFFERS)
  2811.         {
  2812.                 /* highlight directories */
  2813.             j = (mch_isdir(files_found[k]));
  2814.             home_replace(NULL, files_found[k], NameBuff, MAXPATHL,
  2815.                                     TRUE);
  2816.             p = NameBuff;
  2817.         }
  2818.         else
  2819.         {
  2820.             j = FALSE;
  2821.             p = files_found[k];
  2822.         }
  2823.         lastlen = msg_outtrans_attr(p, j ? attr : 0);
  2824.         }
  2825.         if (msg_col > 0)    /* when not wrapped around */
  2826.         {
  2827.         msg_clr_eos();
  2828.         msg_putchar('\n');
  2829.         }
  2830.         out_flush();            /* show one line at a time */
  2831.         if (got_int)
  2832.         {
  2833.         got_int = FALSE;
  2834.         break;
  2835.         }
  2836.     }
  2837.  
  2838.     /*
  2839.      * we redraw the command below the lines that we have just listed
  2840.      * This is a bit tricky, but it saves a lot of screen updating.
  2841.      */
  2842.     cmdline_row = msg_row;    /* will put it back later */
  2843.     }
  2844.  
  2845.     if (cmd_numfiles == -1)
  2846.     FreeWild(num_files, files_found);
  2847.  
  2848.     return EXPAND_OK;
  2849. }
  2850.  
  2851. /*
  2852.  * Prepare a string for expansion.
  2853.  * When expanding file names: The string will be used with expand_wildcards().
  2854.  * Copy the file name into allocated memory and add a '*' at the end.
  2855.  * When expanding other names: The string will be used with regcomp().  Copy
  2856.  * the name into allocated memory and add ".*" at the end.
  2857.  */
  2858.     char_u *
  2859. addstar(fname, len, context)
  2860.     char_u    *fname;
  2861.     int        len;
  2862.     int        context;    /* EXPAND_FILES etc. */
  2863. {
  2864.     char_u    *retval;
  2865.     int        i, j;
  2866.     int        new_len;
  2867.     char_u    *tail;
  2868.  
  2869.     if (context != EXPAND_FILES && context != EXPAND_DIRECTORIES)
  2870.     {
  2871.     /*
  2872.      * Matching will be done internally (on something other than files).
  2873.      * So we convert the file-matching-type wildcards into our kind for
  2874.      * use with vim_regcomp().  First work out how long it will be:
  2875.      */
  2876.  
  2877.     /* for help tags the translation is done in find_help_tags() */
  2878.     if (context == EXPAND_HELP
  2879.         || context == EXPAND_COLORS
  2880.         || context == EXPAND_COMPILER)
  2881.         retval = vim_strnsave(fname, len);
  2882.     else
  2883.     {
  2884.         new_len = len + 2;        /* +2 for '^' at start, NUL at end */
  2885.         for (i = 0; i < len; i++)
  2886.         {
  2887.         if (fname[i] == '*' || fname[i] == '~')
  2888.             new_len++;        /* '*' needs to be replaced by ".*"
  2889.                        '~' needs to be replaced by "\~" */
  2890.  
  2891.         /* Buffer names are like file names.  "." should be literal */
  2892.         if (context == EXPAND_BUFFERS && fname[i] == '.')
  2893.             new_len++;        /* "." becomes "\." */
  2894.         }
  2895.         retval = alloc(new_len);
  2896.         if (retval != NULL)
  2897.         {
  2898.         retval[0] = '^';
  2899.         j = 1;
  2900.         for (i = 0; i < len; i++, j++)
  2901.         {
  2902.             if (fname[i] == '\\' && ++i == len)    /* skip backslash */
  2903.             break;
  2904.  
  2905.             switch (fname[i])
  2906.             {
  2907.             case '*':   retval[j++] = '.';
  2908.                     break;
  2909.             case '~':   retval[j++] = '\\';
  2910.                     break;
  2911.             case '?':   retval[j] = '.';
  2912.                     continue;
  2913.             case '.':   if (context == EXPAND_BUFFERS)
  2914.                     retval[j++] = '\\';
  2915.                     break;
  2916.             }
  2917.             retval[j] = fname[i];
  2918.         }
  2919.         retval[j] = NUL;
  2920.         }
  2921.     }
  2922.     }
  2923.     else
  2924.     {
  2925.     retval = alloc(len + 4);
  2926.     if (retval != NULL)
  2927.     {
  2928.         STRNCPY(retval, fname, len);
  2929.         retval[len] = NUL;
  2930.  
  2931.         /*
  2932.          * Don't add a star to ~, ~user, $var or `cmd`.
  2933.          * ~ would be at the start of the file name, but not the tail.
  2934.          * $ could be anywhere in the tail.
  2935.          * ` could be anywhere in the file name.
  2936.          */
  2937.         tail = gettail(retval);
  2938.         if ((*retval != '~' || tail != retval)
  2939.             && vim_strchr(tail, '$') == NULL
  2940.             && vim_strchr(retval, '`') == NULL)
  2941.         retval[len++] = '*';
  2942.         retval[len] = NUL;
  2943.     }
  2944.     }
  2945.     return retval;
  2946. }
  2947.  
  2948. /*
  2949.  * Must parse the command line so far to work out what context we are in.
  2950.  * Completion can then be done based on that context.
  2951.  * This routine sets the variables:
  2952.  *  xp->xp_pattern        The start of the pattern to be expanded within
  2953.  *                the command line (ends at the cursor).
  2954.  *  xp->xp_context        The type of thing to expand.  Will be one of:
  2955.  *
  2956.  *  EXPAND_UNSUCCESSFUL        Used sometimes when there is something illegal on
  2957.  *                the command line, like an unknown command.    Caller
  2958.  *                should beep.
  2959.  *  EXPAND_NOTHING        Unrecognised context for completion, use char like
  2960.  *                a normal char, rather than for completion.    eg
  2961.  *                :s/^I/
  2962.  *  EXPAND_COMMANDS        Cursor is still touching the command, so complete
  2963.  *                it.
  2964.  *  EXPAND_BUFFERS        Complete file names for :buf and :sbuf commands.
  2965.  *  EXPAND_FILES        After command with XFILE set, or after setting
  2966.  *                with P_EXPAND set.    eg :e ^I, :w>>^I
  2967.  *  EXPAND_DIRECTORIES        In some cases this is used instead of the latter
  2968.  *                when we know only directories are of interest.  eg
  2969.  *                :set dir=^I
  2970.  *  EXPAND_SETTINGS        Complete variable names.  eg :set d^I
  2971.  *  EXPAND_BOOL_SETTINGS    Complete boolean variables only,  eg :set no^I
  2972.  *  EXPAND_TAGS            Complete tags from the files in p_tags.  eg :ta a^I
  2973.  *  EXPAND_TAGS_LISTFILES   As above, but list filenames on ^D, after :tselect
  2974.  *  EXPAND_HELP            Complete tags from the file 'helpfile'/tags
  2975.  *  EXPAND_EVENTS        Complete event names
  2976.  *  EXPAND_SYNTAX        Complete :syntax command arguments
  2977.  *  EXPAND_HIGHLIGHT        Complete highlight (syntax) group names
  2978.  *  EXPAND_AUGROUP        Complete autocommand group names
  2979.  *  EXPAND_USER_VARS        Complete user defined variable names, eg :unlet a^I
  2980.  *  EXPAND_MAPPINGS        Complete mapping and abbreviation names,
  2981.  *                  eg :unmap a^I , :cunab x^I
  2982.  *  EXPAND_FUNCTIONS        Complete internal or user defined function names,
  2983.  *                  eg :call sub^I
  2984.  *  EXPAND_USER_FUNC        Complete user defined function names, eg :delf F^I
  2985.  *  EXPAND_EXPRESSION        Complete internal or user defined function/variable
  2986.  *                names in expressions, eg :while s^I
  2987.  *  EXPAND_ENV_VARS        Complete environment variable names
  2988.  */
  2989.     static void
  2990. set_expand_context(xp)
  2991.     expand_T    *xp;
  2992. {
  2993.     /* only expansion for ':' and '>' commands */
  2994.     if (ccline.cmdfirstc != ':'
  2995. #ifdef FEAT_EVAL
  2996.         && ccline.cmdfirstc != '>'
  2997. #endif
  2998.         )
  2999.     {
  3000.     xp->xp_context = EXPAND_NOTHING;
  3001.     return;
  3002.     }
  3003.     set_cmd_context(xp, ccline.cmdbuff, ccline.cmdlen, ccline.cmdpos);
  3004. }
  3005.  
  3006.     void
  3007. set_cmd_context(xp, str, len, col)
  3008.     expand_T    *xp;
  3009.     char_u    *str;        /* start of command line */
  3010.     int        len;        /* length of command line (excl. NUL) */
  3011.     int        col;        /* position of cursor */
  3012. {
  3013.     int        old_char = NUL;
  3014.     char_u    *nextcomm;
  3015.  
  3016.     /*
  3017.      * Avoid a UMR warning from Purify, only save the character if it has been
  3018.      * written before.
  3019.      */
  3020.     if (col < len)
  3021.     old_char = str[col];
  3022.     str[col] = NUL;
  3023.     nextcomm = str;
  3024.     while (nextcomm != NULL)
  3025.     nextcomm = set_one_cmd_context(xp, nextcomm);
  3026.     str[col] = old_char;
  3027. }
  3028.  
  3029. /*
  3030.  * Expand the command line "str" from context "xp".
  3031.  * "xp" must have been set by set_cmd_context().
  3032.  * xp->xp_pattern points into "str", to where the text that is to be expanded
  3033.  * starts.
  3034.  * Returns EXPAND_UNSUCCESSFUL when there is something illegal before the
  3035.  * cursor.
  3036.  * Returns EXPAND_NOTHING when there is nothing to expand, might insert the
  3037.  * key that triggered expansion literally.
  3038.  * Returns EXPAND_OK otherwise.
  3039.  */
  3040.     int
  3041. expand_cmdline(xp, str, col, matchcount, matches)
  3042.     expand_T    *xp;
  3043.     char_u    *str;        /* start of command line */
  3044.     int        col;        /* position of cursor */
  3045.     int        *matchcount;    /* return: nr of matches */
  3046.     char_u    ***matches;    /* return: array of pointers to matches */
  3047. {
  3048.     char_u    *file_str = NULL;
  3049.  
  3050.     if (xp->xp_context == EXPAND_UNSUCCESSFUL)
  3051.     {
  3052.     beep_flush();
  3053.     return EXPAND_UNSUCCESSFUL;  /* Something illegal on command line */
  3054.     }
  3055.     if (xp->xp_context == EXPAND_NOTHING)
  3056.     {
  3057.     /* Caller can use the character as a normal char instead */
  3058.     return EXPAND_NOTHING;
  3059.     }
  3060.  
  3061.     /* add star to file name, or convert to regexp if not exp. files. */
  3062.     file_str = addstar(xp->xp_pattern,
  3063.                (int)(str + col - xp->xp_pattern), xp->xp_context);
  3064.     if (file_str == NULL)
  3065.     return EXPAND_UNSUCCESSFUL;
  3066.  
  3067.     /* find all files that match the description */
  3068.     if (ExpandFromContext(xp, file_str, matchcount, matches,
  3069.                       WILD_ADD_SLASH|WILD_SILENT) == FAIL)
  3070.     {
  3071.     *matchcount = 0;
  3072.     *matches = NULL;
  3073.     }
  3074.     vim_free(file_str);
  3075.  
  3076.     return EXPAND_OK;
  3077. }
  3078.  
  3079. /*
  3080.  * Do the expansion based on xp->xp_context and "pat".
  3081.  */
  3082.     static int
  3083. ExpandFromContext(xp, pat, num_file, file, options)
  3084.     expand_T    *xp;
  3085.     char_u    *pat;
  3086.     int        *num_file;
  3087.     char_u    ***file;
  3088.     int        options;
  3089. {
  3090. #ifdef FEAT_CMDL_COMPL
  3091.     regmatch_T    regmatch;
  3092. #endif
  3093.     int        ret;
  3094.     int        flags;
  3095.  
  3096.     flags = EW_DIR;    /* include directories */
  3097.     if (options & WILD_LIST_NOTFOUND)
  3098.     flags |= EW_NOTFOUND;
  3099.     if (options & WILD_ADD_SLASH)
  3100.     flags |= EW_ADDSLASH;
  3101.     if (options & WILD_KEEP_ALL)
  3102.     flags |= EW_KEEPALL;
  3103.     if (options & WILD_SILENT)
  3104.     flags |= EW_SILENT;
  3105.  
  3106.     if (xp->xp_context == EXPAND_FILES)
  3107.     {
  3108.     /*
  3109.      * Expand file names.
  3110.      */
  3111.     return expand_wildcards(1, &pat, num_file, file, flags|EW_FILE);
  3112.     }
  3113.     else if (xp->xp_context == EXPAND_DIRECTORIES)
  3114.     {
  3115.     /*
  3116.      * Expand directory names.
  3117.      */
  3118.     int    free_pat = FALSE;
  3119.     int    i;
  3120.  
  3121.     /* for ":set path=" we need to remove backslashes for escaped space */
  3122.     if (xp->xp_set_path)
  3123.     {
  3124.         free_pat = TRUE;
  3125.         pat = vim_strsave(pat);
  3126.         for (i = 0; pat[i]; ++i)
  3127.         if (pat[i] == '\\'
  3128.             && pat[i + 1] == '\\'
  3129.             && pat[i + 2] == '\\'
  3130.             && pat[i + 3] == ' ')
  3131.             STRCPY(pat + i, pat + i + 3);
  3132.     }
  3133.  
  3134.     ret = expand_wildcards(1, &pat, num_file, file,
  3135.                          (flags | EW_DIR) & ~EW_FILE);
  3136.     if (free_pat)
  3137.         vim_free(pat);
  3138.     return ret;
  3139.     }
  3140.  
  3141.     *file = (char_u **)"";
  3142.     *num_file = 0;
  3143.     if (xp->xp_context == EXPAND_HELP)
  3144.     return find_help_tags(pat, num_file, file);
  3145.  
  3146. #ifndef FEAT_CMDL_COMPL
  3147.     return FAIL;
  3148. #else
  3149.     if (xp->xp_context == EXPAND_OLD_SETTING)
  3150.     return ExpandOldSetting(num_file, file);
  3151.     if (xp->xp_context == EXPAND_BUFFERS)
  3152.     return ExpandBufnames(pat, num_file, file, options);
  3153.     if (xp->xp_context == EXPAND_TAGS
  3154.         || xp->xp_context == EXPAND_TAGS_LISTFILES)
  3155.     return expand_tags(xp->xp_context == EXPAND_TAGS, pat, num_file, file);
  3156.     if (xp->xp_context == EXPAND_COLORS)
  3157.     return ExpandRTDir(pat, num_file, file, "colors");
  3158.     if (xp->xp_context == EXPAND_COMPILER)
  3159.     return ExpandRTDir(pat, num_file, file, "compiler");
  3160.  
  3161.     regmatch.regprog = vim_regcomp(pat, (int)p_magic);
  3162.     if (regmatch.regprog == NULL)
  3163.     return FAIL;
  3164.  
  3165.     /* set ignore-case according to p_ic, p_scs and pat */
  3166.     regmatch.rm_ic = ignorecase(pat);
  3167.  
  3168.     if (xp->xp_context == EXPAND_SETTINGS
  3169.         || xp->xp_context == EXPAND_BOOL_SETTINGS)
  3170.     ret = ExpandSettings(xp, ®match, num_file, file);
  3171.     else if (xp->xp_context == EXPAND_MAPPINGS)
  3172.     ret = ExpandMappings(®match, num_file, file);
  3173.     else
  3174.     {
  3175.     static struct expgen
  3176.     {
  3177.         int        context;
  3178.         char_u    *((*func)__ARGS((expand_T *, int)));
  3179.         int        ic;
  3180.     } tab[] =
  3181.     {
  3182.         {EXPAND_COMMANDS, get_command_name, FALSE},
  3183. #ifdef FEAT_USR_CMDS
  3184.         {EXPAND_USER_COMMANDS, get_user_commands, FALSE},
  3185.         {EXPAND_USER_CMD_FLAGS, get_user_cmd_flags, FALSE},
  3186.         {EXPAND_USER_NARGS, get_user_cmd_nargs, FALSE},
  3187.         {EXPAND_USER_COMPLETE, get_user_cmd_complete, FALSE},
  3188. #endif
  3189. #ifdef FEAT_EVAL
  3190.         {EXPAND_USER_VARS, get_user_var_name, FALSE},
  3191.         {EXPAND_FUNCTIONS, get_function_name, FALSE},
  3192.         {EXPAND_USER_FUNC, get_user_func_name, FALSE},
  3193.         {EXPAND_EXPRESSION, get_expr_name, FALSE},
  3194. #endif
  3195. #ifdef FEAT_MENU
  3196.         {EXPAND_MENUS, get_menu_name, FALSE},
  3197.         {EXPAND_MENUNAMES, get_menu_names, FALSE},
  3198. #endif
  3199. #ifdef FEAT_SYN_HL
  3200.         {EXPAND_SYNTAX, get_syntax_name, TRUE},
  3201. #endif
  3202.         {EXPAND_HIGHLIGHT, get_highlight_name, TRUE},
  3203. #ifdef FEAT_AUTOCMD
  3204.         {EXPAND_EVENTS, get_event_name, TRUE},
  3205.         {EXPAND_AUGROUP, get_augroup_name, TRUE},
  3206. #endif
  3207. #if (defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
  3208.     && (defined(FEAT_GETTEXT) || defined(FEAT_MBYTE))
  3209.         {EXPAND_LANGUAGE, get_lang_arg, TRUE},
  3210. #endif
  3211.         {EXPAND_ENV_VARS, get_env_name, TRUE},
  3212.     };
  3213.     int    i;
  3214.  
  3215.     /*
  3216.      * Find a context in the table and call the ExpandGeneric() with the
  3217.      * right function to do the expansion.
  3218.      */
  3219.     ret = FAIL;
  3220.     for (i = 0; i < sizeof(tab) / sizeof(struct expgen); ++i)
  3221.         if (xp->xp_context == tab[i].context)
  3222.         {
  3223.         if (tab[i].ic)
  3224.             regmatch.rm_ic = TRUE;
  3225.         ret = ExpandGeneric(xp, ®match, num_file, file, tab[i].func);
  3226.         break;
  3227.         }
  3228.     }
  3229.  
  3230.     vim_free(regmatch.regprog);
  3231.  
  3232.     return ret;
  3233. #endif /* FEAT_CMDL_COMPL */
  3234. }
  3235.  
  3236. #if defined(FEAT_CMDL_COMPL) || defined(PROTO)
  3237. /*
  3238.  * Expand a list of names.
  3239.  *
  3240.  * Generic function for command line completion.  It calls a function to
  3241.  * obtain strings, one by one.    The strings are matched against a regexp
  3242.  * program.  Matching strings are copied into an array, which is returned.
  3243.  *
  3244.  * Returns OK when no problems encountered, FAIL for error (out of memory).
  3245.  */
  3246.     int
  3247. ExpandGeneric(xp, regmatch, num_file, file, func)
  3248.     expand_T    *xp;
  3249.     regmatch_T    *regmatch;
  3250.     int        *num_file;
  3251.     char_u    ***file;
  3252.     char_u    *((*func)__ARGS((expand_T *, int)));
  3253.                       /* returns a string from the list */
  3254. {
  3255.     int        i;
  3256.     int        count = 0;
  3257.     int        loop;
  3258.     char_u    *str;
  3259.  
  3260.     /* do this loop twice:
  3261.      * loop == 0: count the number of matching names
  3262.      * loop == 1: copy the matching names into allocated memory
  3263.      */
  3264.     for (loop = 0; loop <= 1; ++loop)
  3265.     {
  3266.     for (i = 0; ; ++i)
  3267.     {
  3268.         str = (*func)(xp, i);
  3269.         if (str == NULL)        /* end of list */
  3270.         break;
  3271.         if (*str == NUL)        /* skip empty strings */
  3272.         continue;
  3273.  
  3274.         if (vim_regexec(regmatch, str, (colnr_T)0))
  3275.         {
  3276.         if (loop)
  3277.         {
  3278.             str = vim_strsave_escaped(str, (char_u *)" \t\\.");
  3279.             (*file)[count] = str;
  3280. #ifdef FEAT_MENU
  3281.             if (func == get_menu_names && str != NULL)
  3282.             {
  3283.             /* test for separator added by get_menu_names() */
  3284.             str += STRLEN(str) - 1;
  3285.             if (*str == '\001')
  3286.                 *str = '.';
  3287.             }
  3288. #endif
  3289.         }
  3290.         ++count;
  3291.         }
  3292.     }
  3293.     if (loop == 0)
  3294.     {
  3295.         if (count == 0)
  3296.         return OK;
  3297.         *num_file = count;
  3298.         *file = (char_u **)alloc((unsigned)(count * sizeof(char_u *)));
  3299.         if (*file == NULL)
  3300.         {
  3301.         *file = (char_u **)"";
  3302.         return FAIL;
  3303.         }
  3304.         count = 0;
  3305.     }
  3306.     }
  3307.     return OK;
  3308. }
  3309.  
  3310. /*
  3311.  * Expand color scheme names: 'runtimepath'/colors/{pat}.vim
  3312.  * or compiler names.
  3313.  */
  3314.     static int
  3315. ExpandRTDir(pat, num_file, file, dirname)
  3316.     char_u    *pat;
  3317.     int        *num_file;
  3318.     char_u    ***file;
  3319.     char    *dirname;    /* "colors" or "compiler" */
  3320. {
  3321.     char_u    *all;
  3322.     char_u    *s;
  3323.     char_u    *e;
  3324.     garray_T    ga;
  3325.  
  3326.     *num_file = 0;
  3327.     *file = NULL;
  3328.     s = alloc((unsigned)(STRLEN(pat) + STRLEN(dirname) + 7));
  3329.     if (s == NULL)
  3330.     return FAIL;
  3331.     sprintf((char *)s, "%s/%s*.vim", dirname, pat);
  3332.     all = globpath(p_rtp, s);
  3333.     vim_free(s);
  3334.     if (all == NULL)
  3335.     return FAIL;
  3336.  
  3337.     ga_init2(&ga, (int)sizeof(char *), 3);
  3338.     for (s = all; *s != NUL; s = e)
  3339.     {
  3340.     e = vim_strchr(s, '\n');
  3341.     if (e == NULL)
  3342.         e = s + STRLEN(s);
  3343.     if (ga_grow(&ga, 1) == FAIL)
  3344.         break;
  3345.     if (e - 4 > s && STRNICMP(e - 4, ".vim", 4) == 0)
  3346.     {
  3347.         for (s = e - 4; s > all; --s)
  3348.         if (*s == '\n' || vim_ispathsep(*s))
  3349.             break;
  3350.         ++s;
  3351.         ((char_u **)ga.ga_data)[ga.ga_len] =
  3352.                         vim_strnsave(s, (int)(e - s - 4));
  3353.         ++ga.ga_len;
  3354.         --ga.ga_room;
  3355.     }
  3356.     if (*e != NUL)
  3357.         ++e;
  3358.     }
  3359.     vim_free(all);
  3360.     *file = ga.ga_data;
  3361.     *num_file = ga.ga_len;
  3362.     return OK;
  3363. }
  3364.  
  3365. #endif
  3366.  
  3367. #if defined(FEAT_CMDL_COMPL) || defined(FEAT_EVAL) || defined(PROTO)
  3368. /*
  3369.  * Expand "file" for all comma-separated directories in "path".
  3370.  * Returns an allocated strings with all matches concatenated, separated by
  3371.  * newlines.  Returns NULL for an error or no matches.
  3372.  */
  3373.     char_u *
  3374. globpath(path, file)
  3375.     char_u    *path;
  3376.     char_u    *file;
  3377. {
  3378.     expand_T    xpc;
  3379.     char_u    *buf;
  3380.     garray_T    ga;
  3381.     int        len;
  3382.     char_u    *p;
  3383.     char_u    **save_cmd_files = cmd_files;
  3384.     int        save_cmd_numfiles = cmd_numfiles;
  3385.  
  3386.     buf = alloc(MAXPATHL);
  3387.     if (buf == NULL)
  3388.     return NULL;
  3389.  
  3390.     /* ExpandOne() uses cmd_files and cmd_numfiles, need to save and restore
  3391.      * them. */
  3392.     cmd_files = NULL;
  3393.     cmd_numfiles = -1;
  3394.  
  3395.     xpc.xp_context = EXPAND_FILES;
  3396.     ga_init2(&ga, 1, 100);
  3397.  
  3398.     /* Loop over all entries in {path}. */
  3399.     while (*path != NUL)
  3400.     {
  3401.     /* Copy one item of the path to buf[] and concatenate the file name. */
  3402.     copy_option_part(&path, buf, MAXPATHL, ",");
  3403.     if (STRLEN(buf) + STRLEN(file) + 2 < MAXPATHL)
  3404.     {
  3405.         add_pathsep(buf);
  3406.         STRCAT(buf, file);
  3407.         p = ExpandOne(&xpc, buf, NULL, WILD_USE_NL|WILD_SILENT, WILD_ALL);
  3408.         if (p != NULL)
  3409.         {
  3410.         len = (int)STRLEN(p);
  3411.         if (ga.ga_data == NULL)
  3412.         {
  3413.             ga.ga_data = p;
  3414.             ga.ga_room = 0;
  3415.             ga.ga_len = len + 1;
  3416.         }
  3417.         else
  3418.         {
  3419.             /* Concatenate new results to previous ones.  Insert a NL
  3420.              * and keep room for the trailing NUL. */
  3421.             ++len;
  3422.             if (ga_grow(&ga, len + 1) == OK)
  3423.             {
  3424.             STRCAT(ga.ga_data, "\n");
  3425.             STRCAT(ga.ga_data, p);
  3426.             ga.ga_len += len;
  3427.             ga.ga_room -= len;
  3428.             }
  3429.             vim_free(p);
  3430.         }
  3431.         }
  3432.     }
  3433.     }
  3434.     vim_free(buf);
  3435.  
  3436.     FreeWild(cmd_numfiles, cmd_files);
  3437.     cmd_files = save_cmd_files;
  3438.     cmd_numfiles = save_cmd_numfiles;
  3439.  
  3440.     return ga.ga_data;
  3441. }
  3442.  
  3443. #endif
  3444.  
  3445. #if defined(FEAT_CMDHIST) || defined(PROTO)
  3446.  
  3447. /*********************************
  3448.  *  Command line history stuff     *
  3449.  *********************************/
  3450.  
  3451. /*
  3452.  * Translate a history character to the associated type number.
  3453.  */
  3454.     static int
  3455. hist_char2type(c)
  3456.     int        c;
  3457. {
  3458.     if (c == ':')
  3459.     return HIST_CMD;
  3460.     if (c == '=')
  3461.     return HIST_EXPR;
  3462.     if (c == '@')
  3463.     return HIST_INPUT;
  3464.     if (c == '>')
  3465.     return HIST_DEBUG;
  3466.     return HIST_SEARCH;        /* must be '?' or '/' */
  3467. }
  3468.  
  3469. /*
  3470.  * Table of history names.
  3471.  * These names are used in :history and various hist...() functions.
  3472.  * It is sufficient to give the significant prefix of a history name.
  3473.  */
  3474.  
  3475. static char *(history_names[]) =
  3476. {
  3477.     "cmd",
  3478.     "search",
  3479.     "expr",
  3480.     "input",
  3481.     "debug",
  3482.     NULL
  3483. };
  3484.  
  3485. /*
  3486.  * init_history() - Initialize the command line history.
  3487.  * Also used to re-allocate the history when the size changes.
  3488.  */
  3489.     static void
  3490. init_history()
  3491. {
  3492.     int        newlen;        /* new length of history table */
  3493.     histentry_T    *temp;
  3494.     int        i;
  3495.     int        j;
  3496.     int        type;
  3497.  
  3498.     /*
  3499.      * If size of history table changed, reallocate it
  3500.      */
  3501.     newlen = (int)p_hi;
  3502.     if (newlen != hislen)            /* history length changed */
  3503.     {
  3504.     for (type = 0; type < HIST_COUNT; ++type)   /* adjust the tables */
  3505.     {
  3506.         if (newlen)
  3507.         {
  3508.         temp = (histentry_T *)lalloc(
  3509.                 (long_u)(newlen * sizeof(histentry_T)), TRUE);
  3510.         if (temp == NULL)   /* out of memory! */
  3511.         {
  3512.             if (type == 0)  /* first one: just keep the old length */
  3513.             {
  3514.             newlen = hislen;
  3515.             break;
  3516.             }
  3517.             /* Already changed one table, now we can only have zero
  3518.              * length for all tables. */
  3519.             newlen = 0;
  3520.             type = -1;
  3521.             continue;
  3522.         }
  3523.         }
  3524.         else
  3525.         temp = NULL;
  3526.         if (newlen == 0 || temp != NULL)
  3527.         {
  3528.         if (hisidx[type] < 0)        /* there are no entries yet */
  3529.         {
  3530.             for (i = 0; i < newlen; ++i)
  3531.             {
  3532.             temp[i].hisnum = 0;
  3533.             temp[i].hisstr = NULL;
  3534.             }
  3535.         }
  3536.         else if (newlen > hislen)    /* array becomes bigger */
  3537.         {
  3538.             for (i = 0; i <= hisidx[type]; ++i)
  3539.             temp[i] = history[type][i];
  3540.             j = i;
  3541.             for ( ; i <= newlen - (hislen - hisidx[type]); ++i)
  3542.             {
  3543.             temp[i].hisnum = 0;
  3544.             temp[i].hisstr = NULL;
  3545.             }
  3546.             for ( ; j < hislen; ++i, ++j)
  3547.             temp[i] = history[type][j];
  3548.         }
  3549.         else                /* array becomes smaller or 0 */
  3550.         {
  3551.             j = hisidx[type];
  3552.             for (i = newlen - 1; ; --i)
  3553.             {
  3554.             if (i >= 0)        /* copy newest entries */
  3555.                 temp[i] = history[type][j];
  3556.             else            /* remove older entries */
  3557.                 vim_free(history[type][j].hisstr);
  3558.             if (--j < 0)
  3559.                 j = hislen - 1;
  3560.             if (j == hisidx[type])
  3561.                 break;
  3562.             }
  3563.             hisidx[type] = newlen - 1;
  3564.         }
  3565.         vim_free(history[type]);
  3566.         history[type] = temp;
  3567.         }
  3568.     }
  3569.     hislen = newlen;
  3570.     }
  3571. }
  3572.  
  3573. /*
  3574.  * Check if command line 'str' is already in history.
  3575.  * If 'move_to_front' is TRUE, matching entry is moved to end of history.
  3576.  */
  3577.     static int
  3578. in_history(type, str, move_to_front)
  3579.     int        type;
  3580.     char_u  *str;
  3581.     int        move_to_front;    /* Move the entry to the front if it exists */
  3582. {
  3583.     int        i;
  3584.     int        last_i = -1;
  3585.  
  3586.     if (hisidx[type] < 0)
  3587.     return FALSE;
  3588.     i = hisidx[type];
  3589.     do
  3590.     {
  3591.     if (history[type][i].hisstr == NULL)
  3592.         return FALSE;
  3593.     if (STRCMP(str, history[type][i].hisstr) == 0)
  3594.     {
  3595.         if (!move_to_front)
  3596.         return TRUE;
  3597.         last_i = i;
  3598.         break;
  3599.     }
  3600.     if (--i < 0)
  3601.         i = hislen - 1;
  3602.     } while (i != hisidx[type]);
  3603.  
  3604.     if (last_i >= 0)
  3605.     {
  3606.     str = history[type][i].hisstr;
  3607.     while (i != hisidx[type])
  3608.     {
  3609.         if (++i >= hislen)
  3610.         i = 0;
  3611.         history[type][last_i] = history[type][i];
  3612.         last_i = i;
  3613.     }
  3614.     history[type][i].hisstr = str;
  3615.     history[type][i].hisnum = ++hisnum[type];
  3616.     return TRUE;
  3617.     }
  3618.     return FALSE;
  3619. }
  3620.  
  3621. /*
  3622.  * Convert history name (from table above) to its HIST_ equivalent.
  3623.  * When "name" is empty, return "cmd" history.
  3624.  * Returns -1 for unknown history name.
  3625.  */
  3626.     int
  3627. get_histtype(name)
  3628.     char_u    *name;
  3629. {
  3630.     int        i;
  3631.     int        len = (int)STRLEN(name);
  3632.  
  3633.     /* No argument: use current history. */
  3634.     if (len == 0)
  3635.     return hist_char2type(ccline.cmdfirstc);
  3636.  
  3637.     for (i = 0; history_names[i] != NULL; ++i)
  3638.     if (STRNICMP(name, history_names[i], len) == 0)
  3639.         return i;
  3640.  
  3641.     if (vim_strchr((char_u *)":=@>?/", name[0]) != NULL && name[1] == NUL)
  3642.     return hist_char2type(name[0]);
  3643.  
  3644.     return -1;
  3645. }
  3646.  
  3647. static int    last_maptick = -1;    /* last seen maptick */
  3648.  
  3649. /*
  3650.  * Add the given string to the given history.  If the string is already in the
  3651.  * history then it is moved to the front.  "histype" may be one of he HIST_
  3652.  * values.
  3653.  */
  3654.     void
  3655. add_to_history(histype, new_entry, in_map)
  3656.     int        histype;
  3657.     char_u    *new_entry;
  3658.     int        in_map;        /* consider maptick when inside a mapping */
  3659. {
  3660.     histentry_T    *hisptr;
  3661.  
  3662.     if (hislen == 0)        /* no history */
  3663.     return;
  3664.  
  3665.     /*
  3666.      * Searches inside the same mapping overwrite each other, so that only
  3667.      * the last line is kept.  Be careful not to remove a line that was moved
  3668.      * down, only lines that were added.
  3669.      */
  3670.     if (histype == HIST_SEARCH && in_map)
  3671.     {
  3672.     if (maptick == last_maptick)
  3673.     {
  3674.         /* Current line is from the same mapping, remove it */
  3675.         hisptr = &history[HIST_SEARCH][hisidx[HIST_SEARCH]];
  3676.         vim_free(hisptr->hisstr);
  3677.         hisptr->hisstr = NULL;
  3678.         hisptr->hisnum = 0;
  3679.         --hisnum[histype];
  3680.         if (--hisidx[HIST_SEARCH] < 0)
  3681.         hisidx[HIST_SEARCH] = hislen - 1;
  3682.     }
  3683.     last_maptick = -1;
  3684.     }
  3685.     if (!in_history(histype, new_entry, TRUE))
  3686.     {
  3687.     if (++hisidx[histype] == hislen)
  3688.         hisidx[histype] = 0;
  3689.     hisptr = &history[histype][hisidx[histype]];
  3690.     vim_free(hisptr->hisstr);
  3691.     hisptr->hisstr = vim_strsave(new_entry);
  3692.     hisptr->hisnum = ++hisnum[histype];
  3693.     if (histype == HIST_SEARCH && in_map)
  3694.         last_maptick = maptick;
  3695.     }
  3696. }
  3697.  
  3698. #if defined(FEAT_EVAL) || defined(PROTO)
  3699.  
  3700. /*
  3701.  * Get identifier of newest history entry.
  3702.  * "histype" may be one of the HIST_ values.
  3703.  */
  3704.     int
  3705. get_history_idx(histype)
  3706.     int        histype;
  3707. {
  3708.     if (hislen == 0 || histype < 0 || histype >= HIST_COUNT
  3709.             || hisidx[histype] < 0)
  3710.     return -1;
  3711.  
  3712.     return history[histype][hisidx[histype]].hisnum;
  3713. }
  3714.  
  3715. /*
  3716.  * Calculate history index from a number:
  3717.  *   num > 0: seen as identifying number of a history entry
  3718.  *   num < 0: relative position in history wrt newest entry
  3719.  * "histype" may be one of the HIST_ values.
  3720.  */
  3721.     static int
  3722. calc_hist_idx(histype, num)
  3723.     int        histype;
  3724.     int        num;
  3725. {
  3726.     int        i;
  3727.     histentry_T    *hist;
  3728.     int        wrapped = FALSE;
  3729.  
  3730.     if (hislen == 0 || histype < 0 || histype >= HIST_COUNT
  3731.             || (i = hisidx[histype]) < 0 || num == 0)
  3732.     return -1;
  3733.  
  3734.     hist = history[histype];
  3735.     if (num > 0)
  3736.     {
  3737.     while (hist[i].hisnum > num)
  3738.         if (--i < 0)
  3739.         {
  3740.         if (wrapped)
  3741.             break;
  3742.         i += hislen;
  3743.         wrapped = TRUE;
  3744.         }
  3745.     if (hist[i].hisnum == num && hist[i].hisstr != NULL)
  3746.         return i;
  3747.     }
  3748.     else if (-num <= hislen)
  3749.     {
  3750.     i += num + 1;
  3751.     if (i < 0)
  3752.         i += hislen;
  3753.     if (hist[i].hisstr != NULL)
  3754.         return i;
  3755.     }
  3756.     return -1;
  3757. }
  3758.  
  3759. /*
  3760.  * Get a history entry by its index.
  3761.  * "histype" may be one of the HIST_ values.
  3762.  */
  3763.     char_u *
  3764. get_history_entry(histype, idx)
  3765.     int        histype;
  3766.     int        idx;
  3767. {
  3768.     idx = calc_hist_idx(histype, idx);
  3769.     if (idx >= 0)
  3770.     return history[histype][idx].hisstr;
  3771.     else
  3772.     return (char_u *)"";
  3773. }
  3774.  
  3775. /*
  3776.  * Clear all entries of a history.
  3777.  * "histype" may be one of the HIST_ values.
  3778.  */
  3779.     int
  3780. clr_history(histype)
  3781.     int        histype;
  3782. {
  3783.     int        i;
  3784.     histentry_T    *hisptr;
  3785.  
  3786.     if (hislen != 0 && histype >= 0 && histype < HIST_COUNT)
  3787.     {
  3788.     hisptr = history[histype];
  3789.     for (i = hislen; i--;)
  3790.     {
  3791.         vim_free(hisptr->hisstr);
  3792.         hisptr->hisnum = 0;
  3793.         hisptr++->hisstr = NULL;
  3794.     }
  3795.     hisidx[histype] = -1;    /* mark history as cleared */
  3796.     hisnum[histype] = 0;    /* reset identifier counter */
  3797.     return OK;
  3798.     }
  3799.     return FAIL;
  3800. }
  3801.  
  3802. /*
  3803.  * Remove all entries matching {str} from a history.
  3804.  * "histype" may be one of the HIST_ values.
  3805.  */
  3806.     int
  3807. del_history_entry(histype, str)
  3808.     int        histype;
  3809.     char_u    *str;
  3810. {
  3811.     regmatch_T    regmatch;
  3812.     histentry_T    *hisptr;
  3813.     int        idx;
  3814.     int        i;
  3815.     int        last;
  3816.     int        found = FALSE;
  3817.  
  3818.     regmatch.regprog = NULL;
  3819.     regmatch.rm_ic = FALSE;    /* always match case */
  3820.     if (hislen != 0
  3821.         && histype >= 0
  3822.         && histype < HIST_COUNT
  3823.         && *str != NUL
  3824.         && (idx = hisidx[histype]) >= 0
  3825.         && (regmatch.regprog = vim_regcomp(str, TRUE)) != NULL)
  3826.     {
  3827.     i = last = idx;
  3828.     do
  3829.     {
  3830.         hisptr = &history[histype][i];
  3831.         if (hisptr->hisstr == NULL)
  3832.         break;
  3833.         if (vim_regexec(®match, hisptr->hisstr, (colnr_T)0))
  3834.         {
  3835.         found = TRUE;
  3836.         vim_free(hisptr->hisstr);
  3837.         hisptr->hisstr = NULL;
  3838.         hisptr->hisnum = 0;
  3839.         }
  3840.         else
  3841.         {
  3842.         if (i != last)
  3843.         {
  3844.             history[histype][last] = *hisptr;
  3845.             hisptr->hisstr = NULL;
  3846.             hisptr->hisnum = 0;
  3847.         }
  3848.         if (--last < 0)
  3849.             last += hislen;
  3850.         }
  3851.         if (--i < 0)
  3852.         i += hislen;
  3853.     } while (i != idx);
  3854.     if (history[histype][idx].hisstr == NULL)
  3855.         hisidx[histype] = -1;
  3856.     }
  3857.     vim_free(regmatch.regprog);
  3858.     return found;
  3859. }
  3860.  
  3861. /*
  3862.  * Remove an indexed entry from a history.
  3863.  * "histype" may be one of the HIST_ values.
  3864.  */
  3865.     int
  3866. del_history_idx(histype, idx)
  3867.     int        histype;
  3868.     int        idx;
  3869. {
  3870.     int        i, j;
  3871.  
  3872.     i = calc_hist_idx(histype, idx);
  3873.     if (i < 0)
  3874.     return FALSE;
  3875.     idx = hisidx[histype];
  3876.     vim_free(history[histype][i].hisstr);
  3877.  
  3878.     /* When deleting the last added search string in a mapping, reset
  3879.      * last_maptick, so that the last added search string isn't deleted again.
  3880.      */
  3881.     if (histype == HIST_SEARCH && maptick == last_maptick && i == idx)
  3882.     last_maptick = -1;
  3883.  
  3884.     while (i != idx)
  3885.     {
  3886.     j = (i + 1) % hislen;
  3887.     history[histype][i] = history[histype][j];
  3888.     i = j;
  3889.     }
  3890.     history[histype][i].hisstr = NULL;
  3891.     history[histype][i].hisnum = 0;
  3892.     if (--i < 0)
  3893.     i += hislen;
  3894.     hisidx[histype] = i;
  3895.     return TRUE;
  3896. }
  3897.  
  3898. #endif /* FEAT_EVAL */
  3899.  
  3900. #if defined(FEAT_CRYPT) || defined(PROTO)
  3901. /*
  3902.  * Very specific function to remove the value in ":set key=val" from the
  3903.  * history.
  3904.  */
  3905.     void
  3906. remove_key_from_history()
  3907. {
  3908.     char_u    *p;
  3909.     int        i;
  3910.  
  3911.     i = hisidx[HIST_CMD];
  3912.     if (i < 0)
  3913.     return;
  3914.     p = history[HIST_CMD][i].hisstr;
  3915.     if (p != NULL)
  3916.     for ( ; *p; ++p)
  3917.         if (STRNCMP(p, "key", 3) == 0 && !isalpha(p[3]))
  3918.         {
  3919.         p = vim_strchr(p + 3, '=');
  3920.         if (p == NULL)
  3921.             break;
  3922.         ++p;
  3923.         for (i = 0; p[i] && !vim_iswhite(p[i]); ++i)
  3924.             if (p[i] == '\\' && p[i + 1])
  3925.             ++i;
  3926.         mch_memmove(p, p + i, STRLEN(p + i) + 1);
  3927.         --p;
  3928.         }
  3929. }
  3930. #endif
  3931.  
  3932. #endif /* FEAT_CMDHIST */
  3933.  
  3934. #if defined(FEAT_QUICKFIX) || defined(FEAT_CMDHIST) || defined(PROTO)
  3935. /*
  3936.  * Get indices "num1,num2" that specify a range within a list (not a range of
  3937.  * text lines in a buffer!) from a string.  Used for ":history" and ":clist".
  3938.  * Returns OK if parsed successfully, otherwise FAIL.
  3939.  */
  3940.     int
  3941. get_list_range(str, num1, num2)
  3942.     char_u    **str;
  3943.     int        *num1;
  3944.     int        *num2;
  3945. {
  3946.     int        len;
  3947.     int        first = FALSE;
  3948.     long    num;
  3949.  
  3950.     *str = skipwhite(*str);
  3951.     if (**str == '-' || isdigit(**str))    /* parse "from" part of range */
  3952.     {
  3953.     vim_str2nr(*str, NULL, &len, FALSE, FALSE, &num, NULL);
  3954.     *str += len;
  3955.     *num1 = (int)num;
  3956.     first = TRUE;
  3957.     }
  3958.     *str = skipwhite(*str);
  3959.     if (**str == ',')            /* parse "to" part of range */
  3960.     {
  3961.     *str = skipwhite(*str + 1);
  3962.     vim_str2nr(*str, NULL, &len, FALSE, FALSE, &num, NULL);
  3963.     if (len > 0)
  3964.     {
  3965.         *num2 = (int)num;
  3966.         *str = skipwhite(*str + len);
  3967.     }
  3968.     else if (!first)        /* no number given at all */
  3969.         return FAIL;
  3970.     }
  3971.     else if (first)            /* only one number given */
  3972.     *num2 = *num1;
  3973.     return OK;
  3974. }
  3975. #endif
  3976.  
  3977. #if defined(FEAT_CMDHIST) || defined(PROTO)
  3978. /*
  3979.  * :history command - print a history
  3980.  */
  3981.     void
  3982. ex_history(eap)
  3983.     exarg_T    *eap;
  3984. {
  3985.     histentry_T    *hist;
  3986.     int        histype1 = HIST_CMD;
  3987.     int        histype2 = HIST_CMD;
  3988.     int        hisidx1 = 1;
  3989.     int        hisidx2 = -1;
  3990.     int        idx;
  3991.     int        i, j, k;
  3992.     char_u    *end;
  3993.     char_u    *arg = eap->arg;
  3994.  
  3995.     if (hislen == 0)
  3996.     {
  3997.     MSG(_("'history' option is zero"));
  3998.     return;
  3999.     }
  4000.  
  4001.     if (!(isdigit(*arg) || *arg == '-' || *arg == ','))
  4002.     {
  4003.     end = arg;
  4004.     while (ASCII_ISALPHA(*end)
  4005.         || vim_strchr((char_u *)":=@>/?", *end) != NULL)
  4006.         end++;
  4007.     i = *end;
  4008.     *end = NUL;
  4009.     histype1 = get_histtype(arg);
  4010.     if (histype1 == -1)
  4011.     {
  4012.         if (STRICMP(arg, "all") == 0)
  4013.         {
  4014.         histype1 = 0;
  4015.         histype2 = HIST_COUNT-1;
  4016.         }
  4017.         else
  4018.         {
  4019.         *end = i;
  4020.         EMSG(_(e_trailing));
  4021.         return;
  4022.         }
  4023.     }
  4024.     else
  4025.         histype2 = histype1;
  4026.     *end = i;
  4027.     }
  4028.     else
  4029.     end = arg;
  4030.     if (!get_list_range(&end, &hisidx1, &hisidx2) || *end != NUL)
  4031.     {
  4032.     EMSG(_(e_trailing));
  4033.     return;
  4034.     }
  4035.  
  4036.     for (; !got_int && histype1 <= histype2; ++histype1)
  4037.     {
  4038.     STRCPY(IObuff, "\n      #  ");
  4039.     STRCAT(STRCAT(IObuff, history_names[histype1]), " history");
  4040.     MSG_PUTS_TITLE(IObuff);
  4041.     idx = hisidx[histype1];
  4042.     hist = history[histype1];
  4043.     j = hisidx1;
  4044.     k = hisidx2;
  4045.     if (j < 0)
  4046.         j = (-j > hislen) ? 0 : hist[(hislen+j+idx+1) % hislen].hisnum;
  4047.     if (k < 0)
  4048.         k = (-k > hislen) ? 0 : hist[(hislen+k+idx+1) % hislen].hisnum;
  4049.     if (idx >= 0 && j <= k)
  4050.         for (i = idx + 1; !got_int; ++i)
  4051.         {
  4052.         if (i == hislen)
  4053.             i = 0;
  4054.         if (hist[i].hisstr != NULL
  4055.             && hist[i].hisnum >= j && hist[i].hisnum <= k)
  4056.         {
  4057.             msg_putchar('\n');
  4058.             sprintf((char *)IObuff, "%c%6d  %s", i == idx ? '>' : ' ',
  4059.                         hist[i].hisnum, hist[i].hisstr);
  4060.             msg_outtrans(IObuff);
  4061.             out_flush();
  4062.         }
  4063.         if (i == idx)
  4064.             break;
  4065.         }
  4066.     }
  4067. }
  4068. #endif
  4069.  
  4070. #if (defined(FEAT_VIMINFO) && defined(FEAT_CMDHIST)) || defined(PROTO)
  4071. static char_u **viminfo_history[HIST_COUNT] = {NULL, NULL, NULL, NULL};
  4072. static int    viminfo_hisidx[HIST_COUNT] = {0, 0, 0, 0};
  4073. static int    viminfo_hislen[HIST_COUNT] = {0, 0, 0, 0};
  4074. static int    viminfo_add_at_front = FALSE;
  4075.  
  4076. static int    hist_type2char __ARGS((int type, int use_question));
  4077.  
  4078. /*
  4079.  * Translate a history type number to the associated character.
  4080.  */
  4081.     static int
  4082. hist_type2char(type, use_question)
  4083.     int        type;
  4084.     int        use_question;        /* use '?' instead of '/' */
  4085. {
  4086.     if (type == HIST_CMD)
  4087.     return ':';
  4088.     if (type == HIST_SEARCH)
  4089.     {
  4090.     if (use_question)
  4091.         return '?';
  4092.     else
  4093.         return '/';
  4094.     }
  4095.     if (type == HIST_EXPR)
  4096.     return '=';
  4097.     return '@';
  4098. }
  4099.  
  4100. /*
  4101.  * Prepare for reading the history from the viminfo file.
  4102.  * This allocates history arrays to store the read history lines.
  4103.  */
  4104.     void
  4105. prepare_viminfo_history(asklen)
  4106.     int        asklen;
  4107. {
  4108.     int        i;
  4109.     int        num;
  4110.     int        type;
  4111.     int        len;
  4112.  
  4113.     init_history();
  4114.     viminfo_add_at_front = (asklen != 0);
  4115.     if (asklen > hislen)
  4116.     asklen = hislen;
  4117.  
  4118.     for (type = 0; type < HIST_COUNT; ++type)
  4119.     {
  4120.     /*
  4121.      * Count the number of empty spaces in the history list.  If there are
  4122.      * more spaces available than we request, then fill them up.
  4123.      */
  4124.     for (i = 0, num = 0; i < hislen; i++)
  4125.         if (history[type][i].hisstr == NULL)
  4126.         num++;
  4127.     len = asklen;
  4128.     if (num > len)
  4129.         len = num;
  4130.     if (len <= 0)
  4131.         viminfo_history[type] = NULL;
  4132.     else
  4133.         viminfo_history[type] =
  4134.            (char_u **)lalloc((long_u)(len * sizeof(char_u *)), FALSE);
  4135.     if (viminfo_history[type] == NULL)
  4136.         len = 0;
  4137.     viminfo_hislen[type] = len;
  4138.     viminfo_hisidx[type] = 0;
  4139.     }
  4140. }
  4141.  
  4142. /*
  4143.  * Accept a line from the viminfo, store it in the history array when it's
  4144.  * new.
  4145.  */
  4146.     int
  4147. read_viminfo_history(virp)
  4148.     vir_T    *virp;
  4149. {
  4150.     int        type;
  4151.     char_u    *val;
  4152.  
  4153.     type = hist_char2type(virp->vir_line[0]);
  4154.     if (viminfo_hisidx[type] < viminfo_hislen[type])
  4155.     {
  4156.     val = viminfo_readstring(virp, 1, TRUE);
  4157.     if (val != NULL)
  4158.     {
  4159.         if (!in_history(type, val, viminfo_add_at_front))
  4160.         viminfo_history[type][viminfo_hisidx[type]++] = val;
  4161.         else
  4162.         vim_free(val);
  4163.     }
  4164.     }
  4165.     return viminfo_readline(virp);
  4166. }
  4167.  
  4168.     void
  4169. finish_viminfo_history()
  4170. {
  4171.     int idx;
  4172.     int i;
  4173.     int    type;
  4174.  
  4175.     for (type = 0; type < HIST_COUNT; ++type)
  4176.     {
  4177.     if (history[type] == NULL)
  4178.         return;
  4179.     idx = hisidx[type] + viminfo_hisidx[type];
  4180.     if (idx >= hislen)
  4181.         idx -= hislen;
  4182.     else if (idx < 0)
  4183.         idx = hislen - 1;
  4184.     if (viminfo_add_at_front)
  4185.         hisidx[type] = idx;
  4186.     else
  4187.     {
  4188.         if (hisidx[type] == -1)
  4189.         hisidx[type] = hislen - 1;
  4190.         do
  4191.         {
  4192.         if (history[type][idx].hisstr != NULL)
  4193.             break;
  4194.         if (++idx == hislen)
  4195.             idx = 0;
  4196.         } while (idx != hisidx[type]);
  4197.         if (idx != hisidx[type] && --idx < 0)
  4198.         idx = hislen - 1;
  4199.     }
  4200.     for (i = 0; i < viminfo_hisidx[type]; i++)
  4201.     {
  4202.         vim_free(history[type][idx].hisstr);
  4203.         history[type][idx].hisstr = viminfo_history[type][i];
  4204.         if (--idx < 0)
  4205.         idx = hislen - 1;
  4206.     }
  4207.     idx += 1;
  4208.     idx %= hislen;
  4209.     for (i = 0; i < viminfo_hisidx[type]; i++)
  4210.     {
  4211.         history[type][idx++].hisnum = ++hisnum[type];
  4212.         idx %= hislen;
  4213.     }
  4214.     vim_free(viminfo_history[type]);
  4215.     viminfo_history[type] = NULL;
  4216.     }
  4217. }
  4218.  
  4219.     void
  4220. write_viminfo_history(fp)
  4221.     FILE    *fp;
  4222. {
  4223.     int        i;
  4224.     int        type;
  4225.     int        num_saved;
  4226.  
  4227.     init_history();
  4228.     if (hislen == 0)
  4229.     return;
  4230.     for (type = 0; type < HIST_COUNT; ++type)
  4231.     {
  4232.     num_saved = get_viminfo_parameter(hist_type2char(type, FALSE));
  4233.     if (num_saved == 0)
  4234.         continue;
  4235.     if (num_saved < 0)  /* Use default */
  4236.         num_saved = hislen;
  4237.     fprintf(fp, _("\n# %s History (newest to oldest):\n"),
  4238.                 type == HIST_CMD ? _("Command Line") :
  4239.                 type == HIST_SEARCH ? _("Search String") :
  4240.                 type == HIST_EXPR ?  _("Expression") :
  4241.                     _("Input Line"));
  4242.     if (num_saved > hislen)
  4243.         num_saved = hislen;
  4244.     i = hisidx[type];
  4245.     if (i >= 0)
  4246.         while (num_saved--)
  4247.         {
  4248.         if (history[type][i].hisstr != NULL)
  4249.         {
  4250.             putc(hist_type2char(type, TRUE), fp);
  4251.             viminfo_writestring(fp, history[type][i].hisstr);
  4252.         }
  4253.         if (--i < 0)
  4254.             i = hislen - 1;
  4255.         }
  4256.     }
  4257. }
  4258. #endif /* FEAT_VIMINFO */
  4259.  
  4260. #if defined(FEAT_FKMAP) || defined(PROTO)
  4261. /*
  4262.  * Write a character at the current cursor+offset position.
  4263.  * It is directly written into the command buffer block.
  4264.  */
  4265.     void
  4266. cmd_pchar(c, offset)
  4267.     int        c, offset;
  4268. {
  4269.     if (ccline.cmdpos + offset >= ccline.cmdlen || ccline.cmdpos + offset < 0)
  4270.     {
  4271.     EMSG(_("E198: cmd_pchar beyond the command length"));
  4272.     return;
  4273.     }
  4274.     ccline.cmdbuff[ccline.cmdpos + offset] = (char_u)c;
  4275.     ccline.cmdbuff[ccline.cmdlen] = NUL;
  4276. }
  4277.  
  4278.     int
  4279. cmd_gchar(offset)
  4280.     int        offset;
  4281. {
  4282.     if (ccline.cmdpos + offset >= ccline.cmdlen || ccline.cmdpos + offset < 0)
  4283.     {
  4284.     /*  EMSG(_("cmd_gchar beyond the command length")); */
  4285.     return NUL;
  4286.     }
  4287.     return (int)ccline.cmdbuff[ccline.cmdpos + offset];
  4288. }
  4289. #endif
  4290.  
  4291. #if defined(FEAT_CMDWIN) || defined(PROTO)
  4292. /*
  4293.  * Open a window on the current command line and history.  Allow editing in
  4294.  * the window.  Returns when the window is closed.
  4295.  * Returns:
  4296.  *    CR     if the command is to be executed
  4297.  *    Ctrl_C     if it is to be abandoned
  4298.  *    K_IGNORE if editing continues
  4299.  */
  4300.     static int
  4301. ex_window()
  4302. {
  4303.     struct cmdline_info    save_ccline;
  4304.     buf_T        *old_curbuf = curbuf;
  4305.     win_T        *old_curwin = curwin;
  4306.     buf_T        *bp;
  4307.     win_T        *wp;
  4308.     int            i;
  4309.     linenr_T        lnum;
  4310.     int            histtype;
  4311.     garray_T        winsizes;
  4312.     char_u        typestr[2];
  4313.     int            save_restart_edit = restart_edit;
  4314.     int            save_State = State;
  4315.  
  4316.     /* Can't do this recursively.  Can't do it when typing a password. */
  4317.     if (cmdwin_type != 0 || cmdline_star > 0)
  4318.     {
  4319.     beep_flush();
  4320.     return K_IGNORE;
  4321.     }
  4322.  
  4323.     /* Save current window sizes. */
  4324.     win_size_save(&winsizes);
  4325.  
  4326. # ifdef FEAT_AUTOCMD
  4327.     /* Don't execute autocommands while creating the window. */
  4328.     ++autocmd_busy;
  4329. # endif
  4330.     /* Create a window for the command-line buffer. */
  4331.     if (win_split((int)p_cwh, WSP_BOT) == FAIL)
  4332.     {
  4333.     beep_flush();
  4334.     return K_IGNORE;
  4335.     }
  4336.     cmdwin_type = ccline.cmdfirstc;
  4337.     if (cmdwin_type == NUL)
  4338.     cmdwin_type = '-';
  4339.  
  4340.     /* Create the command-line buffer empty. */
  4341.     (void)do_ecmd(0, NULL, NULL, NULL, ECMD_ONE, ECMD_HIDE);
  4342.     (void)setfname((char_u *)"command-line", NULL, TRUE);
  4343.     set_option_value((char_u *)"bt", 0L, (char_u *)"nofile", OPT_LOCAL);
  4344.     set_option_value((char_u *)"swf", 0L, NULL, OPT_LOCAL);
  4345.     curbuf->b_p_ma = TRUE;
  4346. # ifdef FEAT_RIGHTLEFT
  4347.     curwin->w_p_rl = FALSE;
  4348. # endif
  4349.  
  4350. # ifdef FEAT_AUTOCMD
  4351.     /* Do execute autocommands for setting the filetype (load syntax). */
  4352.     --autocmd_busy;
  4353. # endif
  4354.  
  4355.     histtype = hist_char2type(ccline.cmdfirstc);
  4356.     if (histtype == HIST_CMD || histtype == HIST_DEBUG)
  4357.     {
  4358.     if (p_wc == TAB)
  4359.     {
  4360.         add_map((char_u *)"<buffer> <Tab> <C-X><C-V>", INSERT);
  4361.         add_map((char_u *)"<buffer> <Tab> a<C-X><C-V>", NORMAL);
  4362.     }
  4363.     set_option_value((char_u *)"ft", 0L, (char_u *)"vim", OPT_LOCAL);
  4364.     }
  4365.  
  4366.     /* Fill the buffer with the history. */
  4367.     init_history();
  4368.     if (hislen > 0)
  4369.     {
  4370.     i = hisidx[histtype];
  4371.     if (i >= 0)
  4372.     {
  4373.         lnum = 0;
  4374.         do
  4375.         {
  4376.         if (++i == hislen)
  4377.             i = 0;
  4378.         if (history[histtype][i].hisstr != NULL)
  4379.             ml_append(lnum++, history[histtype][i].hisstr,
  4380.                                (colnr_T)0, FALSE);
  4381.         }
  4382.         while (i != hisidx[histtype]);
  4383.     }
  4384.     }
  4385.  
  4386.     /* Replace the empty last line with the current command-line and put the
  4387.      * cursor there. */
  4388.     ml_replace(curbuf->b_ml.ml_line_count, ccline.cmdbuff, TRUE);
  4389.     curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
  4390.     curwin->w_cursor.col = ccline.cmdpos;
  4391.     redraw_later(NOT_VALID);
  4392.  
  4393.     /* Save the command line info, can be used recursively. */
  4394.     save_ccline = ccline;
  4395.     ccline.cmdbuff = NULL;
  4396.     ccline.cmdprompt = NULL;
  4397.  
  4398.     State = NORMAL;
  4399. # ifdef FEAT_MOUSE
  4400.     setmouse();
  4401. # endif
  4402.  
  4403. # ifdef FEAT_AUTOCMD
  4404.     /* Trigger CmdwinEnter autocommands. */
  4405.     typestr[0] = cmdwin_type;
  4406.     typestr[1] = NUL;
  4407.     apply_autocmds(EVENT_CMDWINENTER, typestr, typestr, FALSE, curbuf);
  4408. # endif
  4409.  
  4410.     i = RedrawingDisabled;
  4411.     RedrawingDisabled = 0;
  4412.  
  4413.     /*
  4414.      * Call the main loop until <CR> or CTRL-C is typed.
  4415.      */
  4416.     cmdwin_result = 0;
  4417.     main_loop(TRUE);
  4418.  
  4419.     RedrawingDisabled = i;
  4420.  
  4421. # ifdef FEAT_AUTOCMD
  4422.     /* Trigger CmdwinLeave autocommands. */
  4423.     apply_autocmds(EVENT_CMDWINLEAVE, typestr, typestr, FALSE, curbuf);
  4424. # endif
  4425.  
  4426.     /* Restore the comand line info. */
  4427.     ccline = save_ccline;
  4428.     cmdwin_type = 0;
  4429.  
  4430.     /* Safety check: The old window or buffer was deleted: It's a a bug when
  4431.      * this happens! */
  4432.     if (!win_valid(old_curwin) || !buf_valid(old_curbuf))
  4433.     {
  4434.     cmdwin_result = Ctrl_C;
  4435.     EMSG(_("E199: Active window or buffer deleted"));
  4436.     }
  4437.     else
  4438.     {
  4439.     /* Set the new command line from the cmdline buffer. */
  4440.     vim_free(ccline.cmdbuff);
  4441.     if (cmdwin_result == K_XF1)        /* :qa! typed */
  4442.     {
  4443.         ccline.cmdbuff = vim_strsave((char_u *)"qa!");
  4444.         cmdwin_result = CR;
  4445.     }
  4446.     else if (cmdwin_result == K_XF2)    /* :qa typed */
  4447.     {
  4448.         ccline.cmdbuff = vim_strsave((char_u *)"qa");
  4449.         cmdwin_result = CR;
  4450.     }
  4451.     else
  4452.         ccline.cmdbuff = vim_strsave(ml_get_curline());
  4453.     if (ccline.cmdbuff == NULL)
  4454.         cmdwin_result = Ctrl_C;
  4455.     else
  4456.     {
  4457.         ccline.cmdlen = (int)STRLEN(ccline.cmdbuff);
  4458.         ccline.cmdbufflen = ccline.cmdlen + 1;
  4459.         ccline.cmdpos = curwin->w_cursor.col;
  4460.         if (ccline.cmdpos > ccline.cmdlen)
  4461.         ccline.cmdpos = ccline.cmdlen;
  4462.         if (cmdwin_result == K_IGNORE)
  4463.         {
  4464.         set_cmdspos_cursor();
  4465.         redrawcmd();
  4466.         /* CTRL-C closes the window but doesn't exe the cmdline */
  4467.         got_int = FALSE;
  4468.         }
  4469.     }
  4470.  
  4471. # ifdef FEAT_AUTOCMD
  4472.     /* Don't execute autocommands while deleting the window. */
  4473.     ++autocmd_busy;
  4474. # endif
  4475.     wp = curwin;
  4476.     bp = curbuf;
  4477.     win_goto(old_curwin);
  4478.     win_close(wp, TRUE);
  4479.     close_buffer(NULL, bp, DOBUF_WIPE);
  4480.  
  4481.     /* Restore window sizes. */
  4482.     win_size_restore(&winsizes);
  4483.  
  4484. # ifdef FEAT_AUTOCMD
  4485.     --autocmd_busy;
  4486. # endif
  4487.     }
  4488.  
  4489.     ga_clear(&winsizes);
  4490.     restart_edit = save_restart_edit;
  4491.  
  4492.     State = save_State;
  4493. # ifdef FEAT_MOUSE
  4494.     setmouse();
  4495. # endif
  4496.  
  4497.     return cmdwin_result;
  4498. }
  4499. #endif /* FEAT_CMDWIN */
  4500.  
  4501. #if defined(FEAT_PYTHON) || defined(FEAT_RUBY) || defined(FEAT_TCL) \
  4502.     || defined(FEAT_PERL) || defined(PROTO)
  4503. /*
  4504.  * Used for commands that either take a simple command string argument, or:
  4505.  *    cmd << endmarker
  4506.  *      {script}
  4507.  *    endmarker
  4508.  * Returns a pointer to allocated memory with {script} or NULL.
  4509.  */
  4510.     char_u *
  4511. script_get(eap, cmd)
  4512.     exarg_T    *eap;
  4513.     char_u    *cmd;
  4514. {
  4515.     char_u    *theline;
  4516.     char    *end_pattern = NULL;
  4517.     char    dot[] = ".";
  4518.     garray_T    ga;
  4519.  
  4520.     if (cmd[0] != '<' || cmd[1] != '<' || eap->getline == NULL)
  4521.     return NULL;
  4522.  
  4523.     ga_init2(&ga, 1, 0x400);
  4524.  
  4525.     if (cmd[2] != NUL)
  4526.     end_pattern = (char *)skipwhite(cmd + 2);
  4527.     else
  4528.     end_pattern = dot;
  4529.  
  4530.     for (;;)
  4531.     {
  4532.     theline = eap->getline(
  4533. #ifdef FEAT_EVAL
  4534.         eap->cstack->cs_whilelevel > 0 ? -1 :
  4535. #endif
  4536.         NUL, eap->cookie, 0);
  4537.  
  4538.     if (theline == NULL || STRCMP(end_pattern, theline) == 0)
  4539.         break;
  4540.  
  4541.     ga_concat(&ga, theline);
  4542.     ga_append(&ga, '\n');
  4543.     vim_free(theline);
  4544.     }
  4545.  
  4546.     return ga.ga_data;
  4547. }
  4548. #endif /* SCRIPTS */
  4549.